Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b1eb1224f5
48
CHANGELOG.md
48
CHANGELOG.md
|
|
@ -2,6 +2,50 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.10.9] - 2018-06-01
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a use-after-free in `CmsContentInfo::sign`.
|
||||
* `SslRef::servername` now returns `None` rather than panicking on a non-UTF8 name.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `MessageDigest::from_nid`.
|
||||
* Added `Nid::signature_algorithms`, `Nid::long_name`, and `Nid::short_name`.
|
||||
* Added early data and early keying material export support for TLS 1.3.
|
||||
* Added `SslRef::verified_chain`.
|
||||
* Added `SslRef::servername_raw` which returns a `&[u8]` rather than `&str`.
|
||||
* Added `SslRef::finished` and `SslRef::peer_finished`.
|
||||
* Added `X509Ref::digest` to replace `X509Ref::fingerprint`.
|
||||
* `X509StoreBuilder` and `X509Store` now implement `Sync` and `Send`.
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `X509Ref::fingerprint` has been deprecated in favor of `X509Ref::digest`.
|
||||
|
||||
## [v0.10.8] - 2018-05-20
|
||||
|
||||
### Fixed
|
||||
|
||||
* `openssl-sys` will now detect Homebrew-installed OpenSSL when installed to a non-default
|
||||
directory.
|
||||
* The `X509_V_ERR_INVALID_CALL`, `X509_V_ERR_STORE_LOOKUP`, and
|
||||
`X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION` constants in `openssl-sys` are now only present when
|
||||
building against 1.1.0g and up rather than 1.1.0.
|
||||
* `SslContextBuilder::max_proto_version` and `SslContextBuilder::min_proto_version` are only present
|
||||
when building against 1.1.0g and up rather than 1.1.0.
|
||||
|
||||
### Added
|
||||
|
||||
* Added `CmsContentInfo::sign`.
|
||||
* Added `Clone` and `ToOwned` implementations to `Rsa` and `RsaRef` respectively.
|
||||
* The `min_proto_version` and `max_proto_version` methods are available when linking against
|
||||
LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* `X509VerifyParam` is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* ALPN support is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL.
|
||||
* `Stack` and `StackRef` are now `Sync` and `Send`.
|
||||
|
||||
## [v0.10.7] - 2018-04-30
|
||||
|
||||
### Added
|
||||
|
|
@ -183,7 +227,9 @@
|
|||
|
||||
Look at the [release tags] for information about older releases.
|
||||
|
||||
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...master
|
||||
[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.9...master
|
||||
[v0.10.9]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.8...openssl-v0.10.9
|
||||
[v0.10.8]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...openssl-v0.10.8
|
||||
[v0.10.7]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.6...openssl-v0.10.7
|
||||
[v0.10.6]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.5...openssl-v0.10.6
|
||||
[v0.10.5]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.4...openssl-v0.10.5
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -48,25 +48,25 @@ make -j$(nproc)
|
|||
make install
|
||||
```
|
||||
|
||||
### OSX
|
||||
### macOS
|
||||
|
||||
Although OpenSSL 0.9.8 is preinstalled on OSX this library is being phased out
|
||||
of OSX and this crate also does not support that version of OpenSSL. To use this
|
||||
crate on OSX you'll need to install OpenSSL via some alternate means, typically
|
||||
Although OpenSSL 0.9.8 is preinstalled on macOS this library is being phased out
|
||||
of macOS and this crate also does not support that version of OpenSSL. To use this
|
||||
crate on macOS you'll need to install OpenSSL via some alternate means, typically
|
||||
Homebrew:
|
||||
|
||||
```bash
|
||||
brew install openssl
|
||||
```
|
||||
|
||||
Occasionally an update of XCode or MacOS will cause the linker to fail after compilation, to rectify this you may want to try and run:
|
||||
Occasionally an update of XCode or macOS will cause the linker to fail after compilation, to rectify this you may want to try and run:
|
||||
|
||||
```bash
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
If Homebrew is installed to the default location of `/usr/local`, OpenSSL will be
|
||||
automatically detected.
|
||||
If you're using latest version of Homebrew which supports `--prefix` command,
|
||||
OpenSSL will be automatically detected.
|
||||
|
||||
### Windows MSVC
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.30"
|
||||
version = "0.9.32"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>",
|
||||
"Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "MIT"
|
||||
|
|
@ -9,6 +9,7 @@ repository = "https://github.com/sfackler/rust-openssl"
|
|||
readme = "README.md"
|
||||
categories = ["cryptography", "external-ffi-bindings"]
|
||||
links = "openssl"
|
||||
build = "build/main.rs"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
pub fn get(openssl_version: Option<u64>, libressl_version: Option<u64>) -> Vec<&'static str> {
|
||||
let mut cfgs = vec![];
|
||||
|
||||
if let Some(libressl_version) = libressl_version {
|
||||
cfgs.push("libressl");
|
||||
|
||||
if libressl_version >= 0x2_05_01_00_0 {
|
||||
cfgs.push("libressl251");
|
||||
}
|
||||
if libressl_version >= 0x2_06_01_00_0 {
|
||||
cfgs.push("libressl261");
|
||||
}
|
||||
if libressl_version >= 0x2_07_00_00_0 {
|
||||
cfgs.push("libressl270");
|
||||
}
|
||||
} else {
|
||||
let openssl_version = openssl_version.unwrap();
|
||||
|
||||
if openssl_version >= 0x1_00_01_00_0 {
|
||||
cfgs.push("ossl101");
|
||||
}
|
||||
if openssl_version >= 0x1_00_02_00_0 {
|
||||
cfgs.push("ossl102");
|
||||
}
|
||||
if openssl_version >= 0x1_00_02_08_0 {
|
||||
cfgs.push("ossl102h");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_00_0 {
|
||||
cfgs.push("ossl110");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_06_0 {
|
||||
cfgs.push("ossl110f");
|
||||
}
|
||||
if openssl_version >= 0x1_01_00_07_0 {
|
||||
cfgs.push("ossl110g");
|
||||
}
|
||||
if openssl_version >= 0x1_01_01_00_0 {
|
||||
cfgs.push("ossl111");
|
||||
}
|
||||
}
|
||||
|
||||
cfgs
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ use std::io::{BufWriter, Write};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
mod cfgs;
|
||||
|
||||
// The set of `OPENSSL_NO_<FOO>`s that we care about.
|
||||
const DEFINES: &'static [&'static str] = &[
|
||||
"OPENSSL_NO_BUF_FREELISTS",
|
||||
|
|
@ -104,6 +106,8 @@ fn find_openssl_dir(target: &str) -> OsString {
|
|||
let host = env::var("HOST").unwrap();
|
||||
|
||||
if host == target && target.contains("apple-darwin") {
|
||||
// Check up default Homebrew installation location first
|
||||
// for quick resolution if possible.
|
||||
let homebrew = Path::new("/usr/local/opt/openssl@1.1");
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
|
|
@ -112,6 +116,22 @@ fn find_openssl_dir(target: &str) -> OsString {
|
|||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
// Calling `brew --prefix <package>` command usually slow and
|
||||
// takes seconds, and will be used only as a last resort.
|
||||
let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]);
|
||||
if let Some(ref output) = output {
|
||||
let homebrew = Path::new(&output);
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
}
|
||||
let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]);
|
||||
if let Some(ref output) = output {
|
||||
let homebrew = Path::new(&output);
|
||||
if homebrew.exists() {
|
||||
return homebrew.to_path_buf().into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try_pkg_config();
|
||||
|
|
@ -409,6 +429,10 @@ See rust-openssl README for more information:
|
|||
}
|
||||
println!("cargo:conf={}", enabled.join(","));
|
||||
|
||||
for cfg in cfgs::get(openssl_version, libressl_version) {
|
||||
println!("cargo:rustc-cfg={}", cfg);
|
||||
}
|
||||
|
||||
if let Some(libressl_version) = libressl_version {
|
||||
println!("cargo:libressl_version_number={:x}", libressl_version);
|
||||
|
||||
|
|
@ -427,8 +451,6 @@ See rust-openssl README for more information:
|
|||
_ => version_error(),
|
||||
};
|
||||
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:rustc-cfg=libressl2{}{}", minor, fix);
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:libressl_version=2{}{}", minor, fix);
|
||||
println!("cargo:version=101");
|
||||
|
|
@ -437,37 +459,22 @@ See rust-openssl README for more information:
|
|||
let openssl_version = openssl_version.unwrap();
|
||||
println!("cargo:version_number={:x}", openssl_version);
|
||||
|
||||
if openssl_version >= 0x1_00_02_08_0 {
|
||||
println!("cargo:rustc-cfg=ossl102h");
|
||||
}
|
||||
|
||||
if openssl_version >= 0x1_01_00_07_0 {
|
||||
println!("cargo:rustc-cfg=ossl110g");
|
||||
}
|
||||
|
||||
if openssl_version >= 0x1_01_02_00_0 {
|
||||
version_error()
|
||||
} else if openssl_version >= 0x1_01_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl111");
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:version=111");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_01_00_06_0 {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:rustc-cfg=ossl110f");
|
||||
println!("cargo:version=110");
|
||||
println!("cargo:patch=f");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_01_00_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:version=110");
|
||||
Version::Openssl11x
|
||||
} else if openssl_version >= 0x1_00_02_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:version=102");
|
||||
Version::Openssl10x
|
||||
} else if openssl_version >= 0x1_00_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
println!("cargo:version=101");
|
||||
Version::Openssl10x
|
||||
} else {
|
||||
|
|
@ -524,10 +531,12 @@ 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()
|
||||
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{}.so", l))
|
||||
|| files.contains(&format!("{}.dll", l))
|
||||
|| files.contains(&format!("lib{}.dylib", l))
|
||||
});
|
||||
match (can_static, can_dylib) {
|
||||
|
|
@ -548,3 +557,16 @@ fn determine_mode(libdir: &Path, libs: &[&str]) -> &'static str {
|
|||
// practices with security libs", let's link dynamically.
|
||||
"dylib"
|
||||
}
|
||||
|
||||
fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option<String> {
|
||||
let out = Command::new(cmd).args(args).output();
|
||||
if let Ok(ref r1) = out {
|
||||
if r1.status.success() {
|
||||
let r2 = String::from_utf8(r1.stdout.clone());
|
||||
if let Ok(r3) = r2 {
|
||||
return Some(r3.trim().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
|
@ -236,8 +236,10 @@ pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7;
|
|||
pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8;
|
||||
pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9;
|
||||
|
||||
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY
|
||||
| EVP_PKEY_OP_VERIFYRECOVER | EVP_PKEY_OP_SIGNCTX
|
||||
pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN
|
||||
| EVP_PKEY_OP_VERIFY
|
||||
| EVP_PKEY_OP_VERIFYRECOVER
|
||||
| EVP_PKEY_OP_SIGNCTX
|
||||
| EVP_PKEY_OP_VERIFYCTX;
|
||||
|
||||
pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT;
|
||||
|
|
@ -1259,21 +1261,23 @@ pub const SSL_VERIFY_NONE: c_int = 0;
|
|||
pub const SSL_VERIFY_PEER: c_int = 1;
|
||||
pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2;
|
||||
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x, ossl101)))]
|
||||
#[cfg(any(ossl102, all(libressl, not(libressl261))))]
|
||||
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x00000010;
|
||||
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
|
||||
#[cfg(libressl261)]
|
||||
pub const SSL_OP_TLSEXT_PADDING: c_ulong = 0x0;
|
||||
pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: c_ulong = 0x00000800;
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
|
||||
#[cfg(not(libressl261))]
|
||||
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x80000000;
|
||||
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
|
||||
#[cfg(libressl261)]
|
||||
pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_LEGACY_SERVER_CONNECT: c_ulong = 0x00000004;
|
||||
#[cfg(not(any(libressl, ossl110f, ossl111)))]
|
||||
#[cfg(not(any(libressl, ossl110f)))]
|
||||
pub const SSL_OP_ALL: c_ulong = 0x80000BFF;
|
||||
#[cfg(any(ossl110f, ossl111))]
|
||||
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
| SSL_OP_LEGACY_SERVER_CONNECT | SSL_OP_TLSEXT_PADDING
|
||||
#[cfg(ossl110f)]
|
||||
pub const SSL_OP_ALL: c_ulong = SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
| SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
| SSL_OP_LEGACY_SERVER_CONNECT
|
||||
| SSL_OP_TLSEXT_PADDING
|
||||
| SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
|
||||
pub const SSL_OP_NO_QUERY_MTU: c_ulong = 0x00001000;
|
||||
pub const SSL_OP_COOKIE_EXCHANGE: c_ulong = 0x00002000;
|
||||
|
|
@ -1285,12 +1289,15 @@ pub const SSL_OP_NO_TLSv1: c_ulong = 0x04000000;
|
|||
pub const SSL_OP_NO_TLSv1_1: c_ulong = 0x10000000;
|
||||
pub const SSL_OP_NO_TLSv1_2: c_ulong = 0x08000000;
|
||||
|
||||
#[cfg(not(any(ossl101, libressl, ossl111)))]
|
||||
#[cfg(all(ossl102, not(ossl111)))]
|
||||
pub const SSL_OP_NO_SSL_MASK: c_ulong =
|
||||
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
|
||||
#[cfg(ossl111)]
|
||||
pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1
|
||||
| SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2
|
||||
pub const SSL_OP_NO_SSL_MASK: c_ulong = SSL_OP_NO_SSLv2
|
||||
| SSL_OP_NO_SSLv3
|
||||
| SSL_OP_NO_TLSv1
|
||||
| SSL_OP_NO_TLSv1_1
|
||||
| SSL_OP_NO_TLSv1_2
|
||||
| SSL_OP_NO_TLSv1_3;
|
||||
|
||||
pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM;
|
||||
|
|
@ -1386,35 +1393,35 @@ pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52;
|
|||
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
|
||||
pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54;
|
||||
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61;
|
||||
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64;
|
||||
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10;
|
||||
|
||||
pub const GEN_OTHERNAME: c_int = 0;
|
||||
|
|
@ -1446,6 +1453,10 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) {
|
|||
BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY)
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_get_digestbynid(type_: c_int) -> *const EVP_MD {
|
||||
EVP_get_digestbyname(OBJ_nid2sn(type_))
|
||||
}
|
||||
|
||||
// EVP_PKEY_CTX_ctrl macros
|
||||
pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(
|
||||
|
|
@ -1519,7 +1530,7 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) -
|
|||
SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void)
|
||||
}
|
||||
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long {
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void)
|
||||
}
|
||||
|
|
@ -1634,9 +1645,9 @@ extern "C" {
|
|||
pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO;
|
||||
pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int;
|
||||
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
|
||||
#[cfg(any(ossl101, libressl))]
|
||||
#[cfg(not(ossl102))]
|
||||
pub fn BIO_new_mem_buf(buf: *mut c_void, len: c_int) -> *mut BIO;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
|
||||
pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
|
||||
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);
|
||||
|
|
@ -1767,11 +1778,11 @@ extern "C" {
|
|||
|
||||
pub fn DH_new() -> *mut DH;
|
||||
pub fn DH_free(dh: *mut DH);
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_1024_160() -> *mut DH;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_2048_224() -> *mut DH;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn DH_get_2048_256() -> *mut DH;
|
||||
|
||||
pub fn EC_KEY_new() -> *mut EC_KEY;
|
||||
|
|
@ -2029,13 +2040,13 @@ extern "C" {
|
|||
e: *mut ENGINE,
|
||||
pkey: *mut EVP_PKEY,
|
||||
) -> c_int;
|
||||
#[cfg(any(ossl101, libressl))]
|
||||
#[cfg(not(ossl102))]
|
||||
pub fn EVP_DigestVerifyFinal(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *mut c_uchar,
|
||||
siglen: size_t,
|
||||
) -> c_int;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn EVP_DigestVerifyFinal(
|
||||
ctx: *mut EVP_MD_CTX,
|
||||
sigret: *const c_uchar,
|
||||
|
|
@ -2095,7 +2106,10 @@ extern "C" {
|
|||
a: *const ASN1_OBJECT,
|
||||
no_name: c_int,
|
||||
) -> c_int;
|
||||
pub fn OBJ_nid2ln(nid: c_int) -> *const c_char;
|
||||
pub fn OBJ_nid2sn(nid: c_int) -> *const c_char;
|
||||
pub fn OBJ_find_sigid_algs(signid: c_int, pdig_nid: *mut c_int, ppkey_nid: *mut c_int)
|
||||
-> c_int;
|
||||
|
||||
pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP;
|
||||
pub fn OCSP_BASICRESP_free(r: *mut OCSP_BASICRESP);
|
||||
|
|
@ -2351,6 +2365,14 @@ extern "C" {
|
|||
k: *mut RSA,
|
||||
) -> c_int;
|
||||
|
||||
pub fn RSA_padding_check_PKCS1_type_2(
|
||||
to: *mut c_uchar,
|
||||
tlen: c_int,
|
||||
f: *const c_uchar,
|
||||
fl: c_int,
|
||||
rsa_len: c_int,
|
||||
) -> c_int;
|
||||
|
||||
pub fn DSA_new() -> *mut DSA;
|
||||
pub fn DSA_free(dsa: *mut DSA);
|
||||
pub fn DSA_size(dsa: *const DSA) -> c_int;
|
||||
|
|
@ -2439,14 +2461,14 @@ extern "C" {
|
|||
pub fn SSL_get_ex_data(ssl: *const SSL, idx: c_int) -> *mut c_void;
|
||||
pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char;
|
||||
pub fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM;
|
||||
pub fn SSL_get_verify_result(ssl: *const SSL) -> c_long;
|
||||
pub fn SSL_shutdown(ssl: *mut SSL) -> c_int;
|
||||
pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509;
|
||||
#[cfg(any(ossl101, libressl))]
|
||||
#[cfg(not(ossl102))]
|
||||
pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY;
|
||||
pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME;
|
||||
pub fn SSL_set_tmp_dh_callback(
|
||||
|
|
@ -2539,9 +2561,9 @@ extern "C" {
|
|||
remove_session_cb: Option<unsafe extern "C" fn(*mut SSL_CTX, *mut SSL_SESSION)>,
|
||||
);
|
||||
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn SSL_CTX_get0_privatekey(ctx: *const SSL_CTX) -> *mut EVP_PKEY;
|
||||
|
||||
pub fn SSL_CTX_set_cipher_list(ssl: *mut SSL_CTX, s: *const c_char) -> c_int;
|
||||
|
|
@ -2600,10 +2622,12 @@ extern "C" {
|
|||
);
|
||||
pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION;
|
||||
pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int;
|
||||
#[cfg(not(any(ossl101, libressl, ossl110f, ossl111)))]
|
||||
#[cfg(all(ossl102, not(ossl110f)))]
|
||||
pub fn SSL_is_server(s: *mut SSL) -> c_int;
|
||||
#[cfg(any(ossl110f, ossl111))]
|
||||
#[cfg(ossl110f)]
|
||||
pub fn SSL_is_server(s: *const SSL) -> c_int;
|
||||
pub fn SSL_get_finished(s: *const SSL, buf: *mut c_void, count: size_t) -> size_t;
|
||||
pub fn SSL_get_peer_finished(s: *const SSL, buf: *mut c_void, count: size_t) -> size_t;
|
||||
|
||||
pub fn SSL_SESSION_free(s: *mut SSL_SESSION);
|
||||
pub fn SSL_SESSION_get_id(s: *const SSL_SESSION, len: *mut c_uint) -> *const c_uchar;
|
||||
|
|
@ -2615,14 +2639,14 @@ extern "C" {
|
|||
) -> *mut SSL_SESSION;
|
||||
pub fn i2d_SSL_SESSION(s: *mut SSL_SESSION, pp: *mut *mut c_uchar) -> c_int;
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn SSL_CTX_set_alpn_protos(s: *mut SSL_CTX, data: *const c_uchar, len: c_uint) -> c_int;
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn SSL_set_alpn_protos(s: *mut SSL, data: *const c_uchar, len: c_uint) -> c_int;
|
||||
|
||||
// FIXME should take an Option<unsafe extern "C" fn>
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn SSL_CTX_set_alpn_select_cb(
|
||||
ssl: *mut SSL_CTX,
|
||||
cb: extern "C" fn(
|
||||
|
|
@ -2635,7 +2659,7 @@ extern "C" {
|
|||
) -> c_int,
|
||||
arg: *mut c_void,
|
||||
);
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn SSL_get0_alpn_selected(s: *const SSL, data: *mut *const c_uchar, len: *mut c_uint);
|
||||
|
||||
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
|
||||
|
|
@ -2727,17 +2751,17 @@ extern "C" {
|
|||
pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION;
|
||||
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint);
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set1_host(
|
||||
param: *mut X509_VERIFY_PARAM,
|
||||
name: *const c_char,
|
||||
namelen: size_t,
|
||||
) -> c_int;
|
||||
#[cfg(not(any(ossl101, libressl)))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn X509_VERIFY_PARAM_set1_ip(
|
||||
param: *mut X509_VERIFY_PARAM,
|
||||
ip: *const c_uchar,
|
||||
|
|
@ -2839,5 +2863,9 @@ extern "C" {
|
|||
);
|
||||
|
||||
pub fn EVP_MD_size(md: *const EVP_MD) -> c_int;
|
||||
pub fn EVP_get_digestbyname(name: *const c_char) -> *const EVP_MD;
|
||||
pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER;
|
||||
|
||||
pub fn SSL_set_connect_state(s: *mut SSL);
|
||||
pub fn SSL_set_accept_state(s: *mut SSL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
|
||||
#[cfg(libressl250)]
|
||||
#[cfg(not(libressl251))]
|
||||
pub use libressl::v250::*;
|
||||
#[cfg(not(libressl250))]
|
||||
pub use libressl::v25x::*;
|
||||
#[cfg(libressl251)]
|
||||
pub use libressl::v251::*;
|
||||
|
||||
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
|
||||
|
||||
#[cfg(libressl250)]
|
||||
#[cfg(not(libressl251))]
|
||||
mod v250;
|
||||
#[cfg(not(libressl250))]
|
||||
mod v25x;
|
||||
#[cfg(libressl251)]
|
||||
mod v251;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct stack_st_ASN1_OBJECT {
|
||||
|
|
@ -337,9 +336,9 @@ pub const SSL_CTRL_OPTIONS: c_int = 32;
|
|||
pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
||||
pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94;
|
||||
|
||||
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
|
||||
#[cfg(libressl261)]
|
||||
pub const SSL_OP_ALL: c_ulong = 0x4;
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
|
||||
#[cfg(not(libressl261))]
|
||||
pub const SSL_OP_ALL: c_ulong = 0x80000014;
|
||||
pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x0;
|
||||
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x0;
|
||||
|
|
@ -352,9 +351,9 @@ pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: c_ulong = 0x0;
|
|||
pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_TLS_D5_BUG: c_ulong = 0x0;
|
||||
pub const SSL_OP_TLS_BLOCK_PADDING_BUG: c_ulong = 0x0;
|
||||
#[cfg(any(libressl261, libressl262, libressl26x, libressl27x))]
|
||||
#[cfg(libressl261)]
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x0;
|
||||
#[cfg(not(any(libressl261, libressl262, libressl26x, libressl27x)))]
|
||||
#[cfg(not(libressl261))]
|
||||
pub const SSL_OP_SINGLE_ECDH_USE: c_ulong = 0x00080000;
|
||||
pub const SSL_OP_SINGLE_DH_USE: c_ulong = 0x00100000;
|
||||
pub const SSL_OP_NO_SSLv2: c_ulong = 0x0;
|
||||
|
|
@ -448,6 +447,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
|
|||
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong {
|
||||
::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
::SSL_CTRL_OPTIONS,
|
||||
op as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_ulong
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
::SSL_CTRL_CLEAR_OPTIONS,
|
||||
op as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_ulong
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
|
||||
pub fn BIO_s_file() -> *mut BIO_METHOD;
|
||||
|
|
@ -540,6 +561,15 @@ extern "C" {
|
|||
unsafe extern "C" fn(*mut ::SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION,
|
||||
>,
|
||||
);
|
||||
#[cfg(libressl261)]
|
||||
pub fn SSL_CTX_set_min_proto_version(ctx: *mut ::SSL_CTX, version: u16) -> c_int;
|
||||
#[cfg(libressl261)]
|
||||
pub fn SSL_CTX_set_max_proto_version(ctx: *mut ::SSL_CTX, version: u16) -> c_int;
|
||||
#[cfg(libressl270)]
|
||||
pub fn SSL_CTX_get_min_proto_version(ctx: *mut ::SSL_CTX) -> c_int;
|
||||
#[cfg(libressl270)]
|
||||
pub fn SSL_CTX_get_max_proto_version(ctx: *mut ::SSL_CTX) -> c_int;
|
||||
|
||||
pub fn X509_get_subject_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
pub fn X509_get_issuer_name(x: *mut ::X509) -> *mut ::X509_NAME;
|
||||
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use libc::{c_int, c_char, c_void, c_long, c_uchar, size_t, c_uint, c_ulong, time_t};
|
||||
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t, time_t};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -84,6 +84,6 @@ pub struct X509_VERIFY_PARAM {
|
|||
pub purpose: c_int,
|
||||
pub trust: c_int,
|
||||
pub depth: c_int,
|
||||
policies: *mut stack_st_ASN1_OBJECT,
|
||||
pub policies: *mut stack_st_ASN1_OBJECT,
|
||||
id: *mut c_void,
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use libc::{c_int, c_long, c_uchar, c_uint, c_ulong};
|
||||
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(not(ossl110))]
|
||||
mod v10x;
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(not(ossl110))]
|
||||
pub use openssl::v10x::*;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
|
|
@ -15,7 +15,7 @@ mod v111;
|
|||
#[cfg(ossl111)]
|
||||
pub use openssl::v111::*;
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106;
|
||||
|
||||
pub const SSL_MODE_SEND_CLIENTHELLO_TIME: c_long = 0x20;
|
||||
|
|
@ -28,9 +28,9 @@ pub const SSL_OP_CISCO_ANYCONNECT: c_ulong = 0x00008000;
|
|||
pub const SSL_OP_NO_COMPRESSION: c_ulong = 0x00020000;
|
||||
pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: c_ulong = 0x00040000;
|
||||
pub const SSL_OP_NO_SSLv3: c_ulong = 0x02000000;
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub const SSL_OP_NO_DTLSv1: c_ulong = 0x04000000;
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub const SSL_OP_NO_DTLSv1_2: c_ulong = 0x08000000;
|
||||
|
||||
pub const X509_V_ERR_UNSPECIFIED: c_int = 1;
|
||||
|
|
@ -55,7 +55,7 @@ pub const CMS_PARTIAL: c_uint = 0x4000;
|
|||
pub const CMS_REUSE_DIGEST: c_uint = 0x8000;
|
||||
pub const CMS_USE_KEYID: c_uint = 0x10000;
|
||||
pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000;
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub const CMS_KEY_PARAM: c_uint = 0x40000;
|
||||
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::ptr;
|
|||
use std::sync::{Mutex, MutexGuard};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
use libc::time_t;
|
||||
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
|
||||
|
||||
|
|
@ -573,9 +573,6 @@ pub struct SSL_CTX {
|
|||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))]
|
||||
srtp_profiles: *mut c_void,
|
||||
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
srtp_profiles: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
alpn_select_cb: *mut c_void,
|
||||
#[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))]
|
||||
|
|
@ -669,7 +666,7 @@ pub struct SRP_CTX {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub struct X509_VERIFY_PARAM {
|
||||
pub name: *mut c_char,
|
||||
pub check_time: time_t,
|
||||
|
|
@ -682,7 +679,7 @@ pub struct X509_VERIFY_PARAM {
|
|||
pub id: *mut X509_VERIFY_PARAM_ID,
|
||||
}
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub enum X509_VERIFY_PARAM_ID {}
|
||||
pub enum PKCS12 {}
|
||||
|
||||
|
|
@ -810,6 +807,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int {
|
|||
::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong {
|
||||
::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
::SSL_CTRL_OPTIONS,
|
||||
op as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_ulong
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong {
|
||||
::SSL_CTX_ctrl(
|
||||
ctx as *mut _,
|
||||
::SSL_CTRL_CLEAR_OPTIONS,
|
||||
op as c_long,
|
||||
ptr::null_mut(),
|
||||
) as c_ulong
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO;
|
||||
pub fn BIO_s_file() -> *mut BIO_METHOD;
|
||||
|
|
@ -925,15 +944,15 @@ extern "C" {
|
|||
loc: c_int,
|
||||
set: c_int,
|
||||
) -> c_int;
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn X509_get0_signature(
|
||||
psig: *mut *mut ::ASN1_BIT_STRING,
|
||||
palg: *mut *mut ::X509_ALGOR,
|
||||
x: *const ::X509,
|
||||
);
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
|
||||
#[cfg(not(ossl101))]
|
||||
#[cfg(ossl102)]
|
||||
pub fn X509_ALGOR_get0(
|
||||
paobj: *mut *mut ::ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ extern "C" {
|
|||
);
|
||||
pub fn SSL_get_client_random(ssl: *const SSL, out: *mut c_uchar, len: size_t) -> size_t;
|
||||
pub fn SSL_get_server_random(ssl: *const SSL, out: *mut c_uchar, len: size_t) -> size_t;
|
||||
pub fn SSL_get0_verified_chain(ssl: *const SSL) -> *mut stack_st_X509;
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ pub const SSL_EXT_TLS1_3_CERTIFICATE: c_uint = 0x1000;
|
|||
pub const SSL_EXT_TLS1_3_NEW_SESSION_TICKET: c_uint = 0x2000;
|
||||
pub const SSL_EXT_TLS1_3_CERTIFICATE_REQUEST: c_uint = 0x4000;
|
||||
|
||||
pub const SSL_READ_EARLY_DATA_ERROR: c_int = 0;
|
||||
pub const SSL_READ_EARLY_DATA_SUCCESS: c_int = 1;
|
||||
pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2;
|
||||
|
||||
extern "C" {
|
||||
pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func);
|
||||
|
|
@ -82,4 +85,24 @@ extern "C" {
|
|||
cookie_len: size_t
|
||||
) -> c_int>
|
||||
);
|
||||
|
||||
pub fn SSL_CTX_set_max_early_data(ctx: *mut ::SSL_CTX, max_early_data: u32) -> c_int;
|
||||
pub fn SSL_CTX_get_max_early_data(ctx: *const ::SSL_CTX) -> u32;
|
||||
pub fn SSL_set_max_early_data(ctx: *mut ::SSL, max_early_data: u32) -> c_int;
|
||||
pub fn SSL_get_max_early_data(ctx: *const ::SSL) -> u32;
|
||||
pub fn SSL_SESSION_set_max_early_data(ctx: *mut ::SSL_SESSION, max_early_data: u32) -> c_int;
|
||||
pub fn SSL_SESSION_get_max_early_data(ctx: *const ::SSL_SESSION) -> u32;
|
||||
|
||||
pub fn SSL_export_keying_material_early(
|
||||
s: *mut ::SSL,
|
||||
out: *mut c_uchar,
|
||||
olen: size_t,
|
||||
label: *const c_char,
|
||||
llen: size_t,
|
||||
context: *const c_uchar,
|
||||
contextlen: size_t,
|
||||
) -> c_int;
|
||||
|
||||
pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int;
|
||||
pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "openssl"
|
||||
version = "0.10.7"
|
||||
version = "0.10.9"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "Apache-2.0"
|
||||
description = "OpenSSL bindings"
|
||||
|
|
@ -18,10 +18,12 @@ v111 = []
|
|||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
cfg-if = "0.1"
|
||||
foreign-types = "0.3.1"
|
||||
lazy_static = "1"
|
||||
libc = "0.2"
|
||||
openssl-sys = { version = "0.9.30", path = "../openssl-sys" }
|
||||
|
||||
openssl-sys = { version = "0.9.32", path = "../openssl-sys" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3"
|
||||
|
|
|
|||
|
|
@ -1,25 +1,6 @@
|
|||
use std::env;
|
||||
|
||||
fn main() {
|
||||
match env::var("DEP_OPENSSL_VERSION") {
|
||||
Ok(ref v) if v == "101" => {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
println!("cargo:rustc-cfg=ossl10x");
|
||||
}
|
||||
Ok(ref v) if v == "102" => {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:rustc-cfg=ossl10x");
|
||||
}
|
||||
Ok(ref v) if v == "110" => {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
}
|
||||
Ok(ref v) if v == "111" => {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:rustc-cfg=ossl111");
|
||||
}
|
||||
_ => panic!("Unable to detect OpenSSL version"),
|
||||
}
|
||||
|
||||
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
}
|
||||
|
|
@ -37,8 +18,32 @@ fn main() {
|
|||
if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") {
|
||||
let version = u64::from_str_radix(&version, 16).unwrap();
|
||||
|
||||
if version >= 0x1_00_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
}
|
||||
if version >= 0x1_00_02_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
}
|
||||
if version >= 0x1_01_00_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
}
|
||||
if version >= 0x1_01_00_07_0 {
|
||||
println!("cargo:rustc-cfg=ossl110g");
|
||||
}
|
||||
if version >= 0x1_01_01_00_0 {
|
||||
println!("cargo:rustc-cfg=ossl111");
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") {
|
||||
let version = u64::from_str_radix(&version, 16).unwrap();
|
||||
|
||||
if version >= 0x2_06_01_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl261");
|
||||
}
|
||||
|
||||
if version >= 0x2_07_00_00_0 {
|
||||
println!("cargo:rustc-cfg=libressl270");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ use std::ptr;
|
|||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBio;
|
||||
use bn::BigNum;
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use string::OpensslString;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::ASN1_GENERALIZEDTIME;
|
||||
|
|
@ -162,7 +162,7 @@ impl Asn1StringRef {
|
|||
///
|
||||
/// [`as_utf8`]: struct.Asn1String.html#method.as_utf8
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) }
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) }
|
||||
}
|
||||
|
||||
/// Return the length of the Asn1String (number of bytes)
|
||||
|
|
@ -241,11 +241,11 @@ foreign_type_and_impl_send_sync! {
|
|||
impl Asn1BitStringRef {
|
||||
/// Returns the Asn1BitString as a slice
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) }
|
||||
unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) }
|
||||
}
|
||||
/// Length of Asn1BitString in number of bytes.
|
||||
pub fn len(&self) -> usize {
|
||||
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize }
|
||||
unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -296,11 +296,13 @@ impl fmt::Display for Asn1ObjectRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::ASN1_STRING_data;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar {
|
||||
ffi::ASN1_STRING_get0_data(s) as *mut _
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::ASN1_STRING_get0_data;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar {
|
||||
ffi::ASN1_STRING_data(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use ffi;
|
||||
use libc::c_int;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
|
||||
use cvt_p;
|
||||
use error::ErrorStack;
|
||||
|
|
@ -68,11 +68,13 @@ impl MemBio {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
use ffi::BIO_new_mem_buf;
|
||||
|
||||
#[cfg(ossl101)]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
|
||||
cfg_if! {
|
||||
if #[cfg(ossl102)] {
|
||||
use ffi::BIO_new_mem_buf;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO {
|
||||
ffi::BIO_new_mem_buf(buf as *mut _, len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,28 +30,39 @@ use foreign_types::{ForeignType, ForeignTypeRef};
|
|||
use libc::c_int;
|
||||
use std::cmp::Ordering;
|
||||
use std::ffi::CString;
|
||||
use std::{fmt, ptr};
|
||||
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
|
||||
use std::{fmt, ptr};
|
||||
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
use asn1::Asn1Integer;
|
||||
use error::ErrorStack;
|
||||
use string::OpensslString;
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, 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_is_negative,
|
||||
};
|
||||
} else {
|
||||
use ffi::{
|
||||
get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
|
||||
get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
|
||||
get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
|
||||
get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
|
||||
get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
|
||||
get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
|
||||
get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
|
||||
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192};
|
||||
get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
|
||||
};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, 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};
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
|
||||
(*bn).neg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for the most significant bits of a randomly generated `BigNum`.
|
||||
pub struct MsbOption(c_int);
|
||||
|
|
@ -361,17 +372,7 @@ impl BigNumRef {
|
|||
|
||||
/// Returns `true` if `self` is negative.
|
||||
pub fn is_negative(&self) -> bool {
|
||||
self._is_negative()
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
fn _is_negative(&self) -> bool {
|
||||
unsafe { (*self.as_ptr()).neg == 1 }
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
fn _is_negative(&self) -> bool {
|
||||
unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
|
||||
unsafe { BN_is_negative(self.as_ptr()) == 1 }
|
||||
}
|
||||
|
||||
/// Returns the number of significant bits in `self`.
|
||||
|
|
@ -1218,7 +1219,7 @@ macro_rules! delegate {
|
|||
$t::$m(self.deref(), oth.deref())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use bio::{MemBio, MemBioSlice};
|
|||
use error::ErrorStack;
|
||||
use libc::c_uint;
|
||||
use pkey::{HasPrivate, PKeyRef};
|
||||
use stack::Stack;
|
||||
use x509::X509;
|
||||
use stack::StackRef;
|
||||
use x509::{X509, X509Ref};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
bitflags! {
|
||||
|
|
@ -130,30 +130,25 @@ impl CmsContentInfo {
|
|||
/// OpenSSL documentation at [`CMS_sign`]
|
||||
///
|
||||
/// [`CMS_sign`]: https://www.openssl.org/docs/manmaster/man3/CMS_sign.html
|
||||
pub fn sign<T: HasPrivate>(
|
||||
signcert: Option<&X509>,
|
||||
pub fn sign<T>(
|
||||
signcert: Option<&X509Ref>,
|
||||
pkey: Option<&PKeyRef<T>>,
|
||||
certs: Option<&Stack<X509>>,
|
||||
certs: Option<&StackRef<X509>>,
|
||||
data: Option<&[u8]>,
|
||||
flags: CMSOptions,
|
||||
) -> Result<CmsContentInfo, ErrorStack> {
|
||||
) -> Result<CmsContentInfo, ErrorStack>
|
||||
where
|
||||
T: HasPrivate,
|
||||
{
|
||||
unsafe {
|
||||
let signcert = match signcert {
|
||||
Some(cert) => cert.as_ptr(),
|
||||
None => ptr::null_mut(),
|
||||
};
|
||||
let pkey = match pkey {
|
||||
Some(pkey) => pkey.as_ptr(),
|
||||
None => ptr::null_mut(),
|
||||
};
|
||||
let data_bio_ptr = match data {
|
||||
Some(data) => MemBioSlice::new(data)?.as_ptr(),
|
||||
None => ptr::null_mut(),
|
||||
};
|
||||
let certs = match certs {
|
||||
Some(certs) => certs.as_ptr(),
|
||||
None => ptr::null_mut(),
|
||||
let signcert = signcert.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let pkey = pkey.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let data_bio = match data {
|
||||
Some(data) => Some(MemBioSlice::new(data)?),
|
||||
None => None,
|
||||
};
|
||||
let data_bio_ptr = data_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
let certs = certs.map_or(ptr::null_mut(), |p| p.as_ptr());
|
||||
|
||||
let cms = cvt_p(ffi::CMS_sign(
|
||||
signcert,
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use foreign_types::{ForeignType, ForeignTypeRef};
|
|||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bn::BigNum;
|
||||
use pkey::{HasParams, Params};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::DH;
|
||||
|
|
@ -48,12 +48,7 @@ impl Dh<Params> {
|
|||
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> {
|
||||
unsafe {
|
||||
let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?);
|
||||
cvt(compat::DH_set0_pqg(
|
||||
dh.0,
|
||||
p.as_ptr(),
|
||||
q.as_ptr(),
|
||||
g.as_ptr(),
|
||||
))?;
|
||||
cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?;
|
||||
mem::forget((p, g, q));
|
||||
Ok(dh)
|
||||
}
|
||||
|
|
@ -111,34 +106,29 @@ impl Dh<Params> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
pub use ffi::DH_set0_pqg;
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
|
||||
pub unsafe fn DH_set0_pqg(
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::DH_set0_pqg;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DH_set0_pqg(
|
||||
dh: *mut ffi::DH,
|
||||
p: *mut ffi::BIGNUM,
|
||||
q: *mut ffi::BIGNUM,
|
||||
g: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
) -> ::libc::c_int {
|
||||
(*dh).p = p;
|
||||
(*dh).q = q;
|
||||
(*dh).g = g;
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use dh::Dh;
|
||||
use bn::BigNum;
|
||||
use dh::Dh;
|
||||
use ssl::{SslContext, SslMethod};
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ use libc::c_int;
|
|||
use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bn::BigNumRef;
|
||||
use error::ErrorStack;
|
||||
use pkey::{HasParams, HasPublic, Private, Public};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
generic_foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::DSA;
|
||||
|
|
@ -101,7 +101,8 @@ where
|
|||
/// Returns the DSA prime parameter of `self`.
|
||||
pub fn p(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let p = compat::pqg(self.as_ptr())[0];
|
||||
let mut p = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut());
|
||||
BigNumRef::from_ptr(p as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +110,8 @@ where
|
|||
/// Returns the DSA sub-prime parameter of `self`.
|
||||
pub fn q(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let q = compat::pqg(self.as_ptr())[1];
|
||||
let mut q = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut());
|
||||
BigNumRef::from_ptr(q as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -117,7 +119,8 @@ where
|
|||
/// Returns the DSA base parameter of `self`.
|
||||
pub fn g(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let g = compat::pqg(self.as_ptr())[2];
|
||||
let mut g = ptr::null();
|
||||
DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g);
|
||||
BigNumRef::from_ptr(g as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -184,24 +187,27 @@ impl<T> fmt::Debug for Dsa<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
use ffi::{self, BIGNUM, DSA};
|
||||
|
||||
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
|
||||
let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null());
|
||||
ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g);
|
||||
[p, q, g]
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::DSA_get0_pqg;
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn DSA_get0_pqg(
|
||||
d: *mut ffi::DSA,
|
||||
p: *mut *const ffi::BIGNUM,
|
||||
q: *mut *const ffi::BIGNUM,
|
||||
g: *mut *const ffi::BIGNUM)
|
||||
{
|
||||
if !p.is_null() {
|
||||
*p = (*d).p;
|
||||
}
|
||||
if !q.is_null() {
|
||||
*q = (*d).q;
|
||||
}
|
||||
if !g.is_null() {
|
||||
*g = (*d).g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
mod compat {
|
||||
use ffi::{BIGNUM, DSA};
|
||||
|
||||
pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] {
|
||||
[(*d).p, (*d).q, (*d).g]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@
|
|||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use std::ptr;
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_n, cvt_p, init};
|
||||
use bn::{BigNumContextRef, BigNumRef};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public};
|
||||
use {cvt, cvt_n, cvt_p, init};
|
||||
|
||||
/// Compressed or Uncompressed conversion
|
||||
///
|
||||
|
|
@ -803,10 +803,10 @@ impl<T> Clone for EcKey<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use bn::{BigNum, BigNumContext};
|
||||
use nid::Nid;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use super::*;
|
||||
use bn::{BigNum, BigNumContext};
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use nid::Nid;
|
||||
|
||||
#[test]
|
||||
fn key_new_by_curve_name() {
|
||||
|
|
@ -823,7 +823,7 @@ mod test {
|
|||
fn dup() {
|
||||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
key.clone();
|
||||
drop(key.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -862,7 +862,8 @@ 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()
|
||||
let bytes = key
|
||||
.public_key()
|
||||
.to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx)
|
||||
.unwrap();
|
||||
|
||||
|
|
@ -877,7 +878,8 @@ mod test {
|
|||
let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
|
||||
let key = EcKey::generate(&group).unwrap();
|
||||
|
||||
let dup_key = EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
|
||||
let dup_key =
|
||||
EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap();
|
||||
let res = dup_key.check_key().unwrap();
|
||||
|
||||
assert!(res == ());
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ use ffi;
|
|||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use bn::{BigNum, BigNumRef};
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
use ec::EcKeyRef;
|
||||
use error::ErrorStack;
|
||||
use pkey::{Private, Public};
|
||||
use {cvt_n, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::ECDSA_SIG;
|
||||
|
|
@ -53,7 +54,7 @@ impl EcdsaSig {
|
|||
pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> {
|
||||
unsafe {
|
||||
let sig = cvt_p(ffi::ECDSA_SIG_new())?;
|
||||
cvt(compat::set_numbers(sig, r.as_ptr(), s.as_ptr()))?;
|
||||
ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr());
|
||||
mem::forget((r, s));
|
||||
Ok(EcdsaSig::from_ptr(sig as *mut _))
|
||||
}
|
||||
|
|
@ -83,8 +84,9 @@ impl EcdsaSig {
|
|||
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
|
||||
pub fn r(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let xs = compat::get_numbers(self.as_ptr());
|
||||
BigNumRef::from_ptr(xs[0] as *mut _)
|
||||
let mut r = ptr::null();
|
||||
ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut());
|
||||
BigNumRef::from_ptr(r as *mut _)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,53 +97,50 @@ impl EcdsaSig {
|
|||
/// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html
|
||||
pub fn s(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let xs = compat::get_numbers(self.as_ptr());
|
||||
BigNumRef::from_ptr(xs[1] as *mut _)
|
||||
let mut s = ptr::null();
|
||||
ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s);
|
||||
BigNumRef::from_ptr(s as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
|
||||
use libc::c_int;
|
||||
use ffi::{self, BIGNUM, ECDSA_SIG};
|
||||
|
||||
pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int {
|
||||
ffi::ECDSA_SIG_set0(sig, r, s)
|
||||
}
|
||||
|
||||
pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
|
||||
let (mut r, mut s) = (ptr::null(), ptr::null());
|
||||
ffi::ECDSA_SIG_get0(sig, &mut r, &mut s);
|
||||
[r, s]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
mod compat {
|
||||
use libc::c_int;
|
||||
use ffi::{BIGNUM, ECDSA_SIG};
|
||||
|
||||
pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int {
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0};
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ECDSA_SIG_set0(
|
||||
sig: *mut ffi::ECDSA_SIG,
|
||||
r: *mut ffi::BIGNUM,
|
||||
s: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
(*sig).r = r;
|
||||
(*sig).s = s;
|
||||
1
|
||||
}
|
||||
|
||||
pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] {
|
||||
[(*sig).r, (*sig).s]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn ECDSA_SIG_get0(
|
||||
sig: *const ffi::ECDSA_SIG,
|
||||
pr: *mut *const ffi::BIGNUM,
|
||||
ps: *mut *const ffi::BIGNUM)
|
||||
{
|
||||
if !pr.is_null() {
|
||||
(*pr) = (*sig).r;
|
||||
}
|
||||
if !ps.is_null() {
|
||||
(*ps) = (*sig).s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use nid::Nid;
|
||||
use super::*;
|
||||
use ec::EcGroup;
|
||||
use ec::EcKey;
|
||||
use super::*;
|
||||
use nid::Nid;
|
||||
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_EC2M"))]
|
||||
static CURVE_IDENTIFER: Nid = Nid::X9_62_PRIME192V1;
|
||||
|
|
@ -171,7 +170,8 @@ mod test {
|
|||
assert!(verification);
|
||||
|
||||
// Signature will not be verified using the incorrect data but the correct public key
|
||||
let verification2 = res.verify(String::from("hello2").as_bytes(), &public_key)
|
||||
let verification2 = res
|
||||
.verify(String::from("hello2").as_bytes(), &public_key)
|
||||
.unwrap();
|
||||
assert!(verification2 == false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,44 @@
|
|||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::fmt;
|
||||
use ffi;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
} else {
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct MessageDigest(*const ffi::EVP_MD);
|
||||
|
||||
impl MessageDigest {
|
||||
pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { MessageDigest(x) }
|
||||
pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self {
|
||||
MessageDigest(x)
|
||||
}
|
||||
|
||||
/// Returns the `MessageDigest` corresponding to an `Nid`.
|
||||
///
|
||||
/// This corresponds to [`EVP_get_digestbynid`].
|
||||
///
|
||||
/// [`EVP_get_digestbynid`]: https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html
|
||||
pub fn from_nid(type_: Nid) -> Option<MessageDigest> {
|
||||
unsafe {
|
||||
let ptr = ffi::EVP_get_digestbynid(type_.as_raw());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(MessageDigest(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn md5() -> MessageDigest {
|
||||
unsafe { MessageDigest(ffi::EVP_md5()) }
|
||||
|
|
@ -229,8 +251,8 @@ impl Drop for Hasher {
|
|||
/// store the digest data.
|
||||
#[derive(Copy)]
|
||||
pub struct DigestBytes {
|
||||
buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
|
||||
len: usize,
|
||||
pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize],
|
||||
pub(crate) len: usize,
|
||||
}
|
||||
|
||||
impl Clone for DigestBytes {
|
||||
|
|
@ -382,12 +404,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_sha256() {
|
||||
let tests = [
|
||||
(
|
||||
let tests = [(
|
||||
"616263",
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
||||
),
|
||||
];
|
||||
)];
|
||||
|
||||
for test in tests.iter() {
|
||||
hash_test(MessageDigest::sha256(), test);
|
||||
|
|
@ -402,4 +422,12 @@ mod tests {
|
|||
hash_test(MessageDigest::ripemd160(), test);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_nid() {
|
||||
assert_eq!(
|
||||
MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(),
|
||||
MessageDigest::sha256().as_ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
#[macro_use]
|
||||
extern crate foreign_types;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
|
@ -53,8 +55,8 @@ pub mod pkcs5;
|
|||
pub mod pkey;
|
||||
pub mod rand;
|
||||
pub mod rsa;
|
||||
pub mod sign;
|
||||
pub mod sha;
|
||||
pub mod sign;
|
||||
pub mod ssl;
|
||||
pub mod stack;
|
||||
pub mod string;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,23 @@
|
|||
//! A collection of numerical identifiers for OpenSSL objects.
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
use libc::{c_char, c_int};
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::str;
|
||||
|
||||
use cvt_p;
|
||||
use error::ErrorStack;
|
||||
|
||||
/// The digest and public-key algorithms associated with a signature.
|
||||
pub struct SignatureAlgorithms {
|
||||
/// The signature's digest.
|
||||
///
|
||||
/// If the signature does not specify a digest, this will be `NID::UNDEF`.
|
||||
pub digest: Nid,
|
||||
|
||||
/// The signature's public-key.
|
||||
pub pkey: Nid,
|
||||
}
|
||||
|
||||
/// A numerical identifier for an OpenSSL object.
|
||||
///
|
||||
|
|
@ -42,6 +59,46 @@ impl Nid {
|
|||
self.0
|
||||
}
|
||||
|
||||
/// Returns the `Nid`s of the digest and public key algorithms associated with a signature ID.
|
||||
///
|
||||
/// This corresponds to `OBJ_find_sigid_algs`.
|
||||
pub fn signature_algorithms(&self) -> Option<SignatureAlgorithms> {
|
||||
unsafe {
|
||||
let mut digest = 0;
|
||||
let mut pkey = 0;
|
||||
if ffi::OBJ_find_sigid_algs(self.0, &mut digest, &mut pkey) == 1 {
|
||||
Some(SignatureAlgorithms {
|
||||
digest: Nid(digest),
|
||||
pkey: Nid(pkey),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the string representation of a `Nid` (long)
|
||||
/// This corresponds to [`OBJ_nid2ln`]
|
||||
///
|
||||
/// [`OBJ_nid2ln`]: https://www.openssl.org/docs/man1.1.0/crypto/OBJ_nid2ln.html
|
||||
pub fn long_name(&self) -> Result<&'static str, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::OBJ_nid2ln(self.0) as *mut c_char)
|
||||
.map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the string representation of a `Nid` (short)
|
||||
/// This corresponds to [`OBJ_nid2sn`]
|
||||
///
|
||||
/// [`OBJ_nid2sn`]: https://www.openssl.org/docs/man1.1.0/crypto/OBJ_nid2sn.html
|
||||
pub fn short_name(&self) -> Result<&'static str, ErrorStack> {
|
||||
unsafe {
|
||||
cvt_p(ffi::OBJ_nid2sn(self.0) as *mut c_char)
|
||||
.map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
pub const UNDEF: Nid = Nid(ffi::NID_undef);
|
||||
pub const ITU_T: Nid = Nid(ffi::NID_itu_t);
|
||||
pub const CCITT: Nid = Nid(ffi::NID_ccitt);
|
||||
|
|
@ -991,3 +1048,73 @@ impl Nid {
|
|||
pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1);
|
||||
pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Nid;
|
||||
|
||||
#[test]
|
||||
fn signature_digest() {
|
||||
let algs = Nid::SHA256WITHRSAENCRYPTION.signature_algorithms().unwrap();
|
||||
assert_eq!(algs.digest, Nid::SHA256);
|
||||
assert_eq!(algs.pkey, Nid::RSAENCRYPTION);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_name_conversion() {
|
||||
let common_name = Nid::COMMONNAME;
|
||||
let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME;
|
||||
let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1;
|
||||
let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS;
|
||||
let ms_ctl_sign = Nid::MS_CTL_SIGN;
|
||||
let undefined_nid = Nid::from_raw(118);
|
||||
|
||||
assert_eq!(common_name.long_name().unwrap(), "commonName");
|
||||
assert_eq!(
|
||||
organizational_unit_name.long_name().unwrap(),
|
||||
"organizationalUnitName"
|
||||
);
|
||||
assert_eq!(
|
||||
aes256_cbc_hmac_sha1.long_name().unwrap(),
|
||||
"aes-256-cbc-hmac-sha1"
|
||||
);
|
||||
assert_eq!(
|
||||
id_cmc_lrapopwitness.long_name().unwrap(),
|
||||
"id-cmc-lraPOPWitness"
|
||||
);
|
||||
assert_eq!(
|
||||
ms_ctl_sign.long_name().unwrap(),
|
||||
"Microsoft Trust List Signing"
|
||||
);
|
||||
assert!(
|
||||
undefined_nid.long_name().is_err(),
|
||||
"undefined_nid should not return a valid value"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_name_conversion() {
|
||||
let common_name = Nid::COMMONNAME;
|
||||
let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME;
|
||||
let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1;
|
||||
let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS;
|
||||
let ms_ctl_sign = Nid::MS_CTL_SIGN;
|
||||
let undefined_nid = Nid::from_raw(118);
|
||||
|
||||
assert_eq!(common_name.short_name().unwrap(), "CN");
|
||||
assert_eq!(organizational_unit_name.short_name().unwrap(), "OU");
|
||||
assert_eq!(
|
||||
aes256_cbc_hmac_sha1.short_name().unwrap(),
|
||||
"AES-256-CBC-HMAC-SHA1"
|
||||
);
|
||||
assert_eq!(
|
||||
id_cmc_lrapopwitness.short_name().unwrap(),
|
||||
"id-cmc-lraPOPWitness"
|
||||
);
|
||||
assert_eq!(ms_ctl_sign.short_name().unwrap(), "msCTLSign");
|
||||
assert!(
|
||||
undefined_nid.short_name().is_err(),
|
||||
"undefined_nid should not return a valid value"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use pkey::{HasPrivate, PKey, PKeyRef, Private};
|
||||
use error::ErrorStack;
|
||||
use x509::{X509, X509Ref};
|
||||
use stack::Stack;
|
||||
use nid::Nid;
|
||||
use pkey::{HasPrivate, PKey, PKeyRef, Private};
|
||||
use stack::Stack;
|
||||
use x509::{X509, X509Ref};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::PKCS12;
|
||||
|
|
@ -172,7 +172,8 @@ impl Pkcs12Builder {
|
|||
let friendly_name = CString::new(friendly_name).unwrap();
|
||||
let pkey = pkey.as_ptr();
|
||||
let cert = cert.as_ptr();
|
||||
let ca = self.ca
|
||||
let ca = self
|
||||
.ca
|
||||
.as_ref()
|
||||
.map(|ca| ca.as_ptr())
|
||||
.unwrap_or(ptr::null_mut());
|
||||
|
|
@ -206,11 +207,11 @@ mod test {
|
|||
use hex;
|
||||
|
||||
use asn1::Asn1Time;
|
||||
use rsa::Rsa;
|
||||
use pkey::PKey;
|
||||
use nid::Nid;
|
||||
use x509::{X509, X509Name};
|
||||
use pkey::PKey;
|
||||
use rsa::Rsa;
|
||||
use x509::extension::KeyUsage;
|
||||
use x509::{X509, X509Name};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -221,14 +222,14 @@ mod test {
|
|||
let parsed = pkcs12.parse("mypass").unwrap();
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap()),
|
||||
hex::encode(parsed.cert.digest(MessageDigest::sha1()).unwrap()),
|
||||
"59172d9313e84459bcff27f967e79e6e9217e584"
|
||||
);
|
||||
|
||||
let chain = parsed.chain.unwrap();
|
||||
assert_eq!(chain.len(), 1);
|
||||
assert_eq!(
|
||||
hex::encode(chain[0].fingerprint(MessageDigest::sha1()).unwrap()),
|
||||
hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()),
|
||||
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
|
||||
);
|
||||
}
|
||||
|
|
@ -279,8 +280,8 @@ mod test {
|
|||
let parsed = pkcs12.parse("mypass").unwrap();
|
||||
|
||||
assert_eq!(
|
||||
parsed.cert.fingerprint(MessageDigest::sha1()).unwrap(),
|
||||
cert.fingerprint(MessageDigest::sha1()).unwrap()
|
||||
&*parsed.cert.digest(MessageDigest::sha1()).unwrap(),
|
||||
&*cert.digest(MessageDigest::sha1()).unwrap()
|
||||
);
|
||||
assert!(parsed.pkey.public_eq(&pkey));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,8 @@ where
|
|||
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn d(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let d = compat::key(self.as_ptr())[2];
|
||||
let mut d = ptr::null();
|
||||
RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d);
|
||||
BigNumRef::from_ptr(d as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -201,7 +202,8 @@ where
|
|||
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn p(&self) -> Option<&BigNumRef> {
|
||||
unsafe {
|
||||
let p = compat::factors(self.as_ptr())[0];
|
||||
let mut p = ptr::null();
|
||||
RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut());
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -217,7 +219,8 @@ where
|
|||
/// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn q(&self) -> Option<&BigNumRef> {
|
||||
unsafe {
|
||||
let q = compat::factors(self.as_ptr())[1];
|
||||
let mut q = ptr::null();
|
||||
RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q);
|
||||
if q.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -233,7 +236,8 @@ where
|
|||
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn dmp1(&self) -> Option<&BigNumRef> {
|
||||
unsafe {
|
||||
let dp = compat::crt_params(self.as_ptr())[0];
|
||||
let mut dp = ptr::null();
|
||||
RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut());
|
||||
if dp.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -249,7 +253,8 @@ where
|
|||
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn dmq1(&self) -> Option<&BigNumRef> {
|
||||
unsafe {
|
||||
let dq = compat::crt_params(self.as_ptr())[1];
|
||||
let mut dq = ptr::null();
|
||||
RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut());
|
||||
if dq.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -265,7 +270,8 @@ where
|
|||
/// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn iqmp(&self) -> Option<&BigNumRef> {
|
||||
unsafe {
|
||||
let qi = compat::crt_params(self.as_ptr())[2];
|
||||
let mut qi = ptr::null();
|
||||
RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi);
|
||||
if qi.is_null() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -391,7 +397,8 @@ where
|
|||
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn n(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let n = compat::key(self.as_ptr())[0];
|
||||
let mut n = ptr::null();
|
||||
RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut());
|
||||
BigNumRef::from_ptr(n as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -403,7 +410,8 @@ where
|
|||
/// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html
|
||||
pub fn e(&self) -> &BigNumRef {
|
||||
unsafe {
|
||||
let e = compat::key(self.as_ptr())[1];
|
||||
let mut e = ptr::null();
|
||||
RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut());
|
||||
BigNumRef::from_ptr(e as *mut _)
|
||||
}
|
||||
}
|
||||
|
|
@ -421,15 +429,10 @@ impl Rsa<Public> {
|
|||
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
|
||||
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
|
||||
cvt(compat::set_key(
|
||||
rsa.0,
|
||||
n.as_ptr(),
|
||||
e.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
))?;
|
||||
let rsa = cvt_p(ffi::RSA_new())?;
|
||||
RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut());
|
||||
mem::forget((n, e));
|
||||
Ok(rsa)
|
||||
Ok(Rsa::from_ptr(rsa))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -498,10 +501,12 @@ impl RsaPrivateKeyBuilder {
|
|||
/// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html
|
||||
pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?);
|
||||
cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))?;
|
||||
let rsa = cvt_p(ffi::RSA_new())?;
|
||||
RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr());
|
||||
mem::forget((n, e, d));
|
||||
Ok(RsaPrivateKeyBuilder { rsa })
|
||||
Ok(RsaPrivateKeyBuilder {
|
||||
rsa: Rsa::from_ptr(rsa),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -512,9 +517,10 @@ impl RsaPrivateKeyBuilder {
|
|||
/// This correspond to [`RSA_set0_factors`].
|
||||
///
|
||||
/// [`RSA_set0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_factors.html
|
||||
// FIXME should be infallible
|
||||
pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(compat::set_factors(self.rsa.0, p.as_ptr(), q.as_ptr()))?;
|
||||
RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr());
|
||||
mem::forget((p, q));
|
||||
}
|
||||
Ok(self)
|
||||
|
|
@ -528,6 +534,7 @@ impl RsaPrivateKeyBuilder {
|
|||
/// This correspond to [`RSA_set0_crt_params`].
|
||||
///
|
||||
/// [`RSA_set0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_crt_params.html
|
||||
// FIXME should be infallible
|
||||
pub fn set_crt_params(
|
||||
self,
|
||||
dmp1: BigNum,
|
||||
|
|
@ -535,12 +542,12 @@ impl RsaPrivateKeyBuilder {
|
|||
iqmp: BigNum,
|
||||
) -> Result<RsaPrivateKeyBuilder, ErrorStack> {
|
||||
unsafe {
|
||||
cvt(compat::set_crt_params(
|
||||
self.rsa.0,
|
||||
RSA_set0_crt_params(
|
||||
self.rsa.as_ptr(),
|
||||
dmp1.as_ptr(),
|
||||
dmq1.as_ptr(),
|
||||
iqmp.as_ptr(),
|
||||
))?;
|
||||
);
|
||||
mem::forget((dmp1, dmq1, iqmp));
|
||||
}
|
||||
Ok(self)
|
||||
|
|
@ -637,89 +644,99 @@ impl<T> fmt::Debug for Rsa<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
|
||||
use ffi::{self, BIGNUM, RSA};
|
||||
use libc::c_int;
|
||||
|
||||
pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
|
||||
let (mut n, mut e, mut d) = (ptr::null(), ptr::null(), ptr::null());
|
||||
ffi::RSA_get0_key(r, &mut n, &mut e, &mut d);
|
||||
[n, e, d]
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors,
|
||||
RSA_set0_crt_params,
|
||||
};
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_get0_key(
|
||||
r: *const ffi::RSA,
|
||||
n: *mut *const ffi::BIGNUM,
|
||||
e: *mut *const ffi::BIGNUM,
|
||||
d: *mut *const ffi::BIGNUM,
|
||||
) {
|
||||
if !n.is_null() {
|
||||
*n = (*r).n;
|
||||
}
|
||||
if !e.is_null() {
|
||||
*e = (*r).e;
|
||||
}
|
||||
if !d.is_null() {
|
||||
*d = (*r).d;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
|
||||
let (mut p, mut q) = (ptr::null(), ptr::null());
|
||||
ffi::RSA_get0_factors(r, &mut p, &mut q);
|
||||
[p, q]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_get0_factors(
|
||||
r: *const ffi::RSA,
|
||||
p: *mut *const ffi::BIGNUM,
|
||||
q: *mut *const ffi::BIGNUM,
|
||||
) {
|
||||
if !p.is_null() {
|
||||
*p = (*r).p;
|
||||
}
|
||||
if !q.is_null() {
|
||||
*q = (*r).q;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] {
|
||||
let (mut dp, mut dq, mut qi) = (ptr::null(), ptr::null(), ptr::null());
|
||||
ffi::RSA_get0_crt_params(r, &mut dp, &mut dq, &mut qi);
|
||||
[dp, dq, qi]
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_get0_crt_params(
|
||||
r: *const ffi::RSA,
|
||||
dmp1: *mut *const ffi::BIGNUM,
|
||||
dmq1: *mut *const ffi::BIGNUM,
|
||||
iqmp: *mut *const ffi::BIGNUM,
|
||||
) {
|
||||
if !dmp1.is_null() {
|
||||
*dmp1 = (*r).dmp1;
|
||||
}
|
||||
if !dmq1.is_null() {
|
||||
*dmq1 = (*r).dmq1;
|
||||
}
|
||||
if !iqmp.is_null() {
|
||||
*iqmp = (*r).iqmp;
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int {
|
||||
ffi::RSA_set0_key(r, n, e, d)
|
||||
}
|
||||
|
||||
pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int {
|
||||
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,
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_set0_key(
|
||||
r: *mut ffi::RSA,
|
||||
n: *mut ffi::BIGNUM,
|
||||
e: *mut ffi::BIGNUM,
|
||||
d: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
mod compat {
|
||||
use ffi::{BIGNUM, RSA};
|
||||
use libc::c_int;
|
||||
|
||||
pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] {
|
||||
[(*r).n, (*r).e, (*r).d]
|
||||
}
|
||||
|
||||
pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] {
|
||||
[(*r).p, (*r).q]
|
||||
}
|
||||
|
||||
pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] {
|
||||
[(*r).dmp1, (*r).dmq1, (*r).iqmp]
|
||||
}
|
||||
|
||||
pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int {
|
||||
(*r).n = n;
|
||||
(*r).e = e;
|
||||
(*r).d = d;
|
||||
1 // TODO: is this right? should it be 0? what's success?
|
||||
1
|
||||
}
|
||||
|
||||
pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_set0_factors(
|
||||
r: *mut ffi::RSA,
|
||||
p: *mut ffi::BIGNUM,
|
||||
q: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
(*r).p = p;
|
||||
(*r).q = q;
|
||||
1 // TODO: is this right? should it be 0? what's success?
|
||||
1
|
||||
}
|
||||
|
||||
pub unsafe fn set_crt_params(
|
||||
r: *mut RSA,
|
||||
dmp1: *mut BIGNUM,
|
||||
dmq1: *mut BIGNUM,
|
||||
iqmp: *mut BIGNUM,
|
||||
#[allow(bad_style)]
|
||||
unsafe fn RSA_set0_crt_params(
|
||||
r: *mut ffi::RSA,
|
||||
dmp1: *mut ffi::BIGNUM,
|
||||
dmq1: *mut ffi::BIGNUM,
|
||||
iqmp: *mut ffi::BIGNUM,
|
||||
) -> c_int {
|
||||
(*r).dmp1 = dmp1;
|
||||
(*r).dmq1 = dmq1;
|
||||
(*r).iqmp = iqmp;
|
||||
1 // TODO: is this right? should it be 0? what's success?
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -751,7 +768,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")
|
||||
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());
|
||||
|
|
@ -791,7 +809,8 @@ mod test {
|
|||
k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1)
|
||||
.unwrap();
|
||||
let mut dmesg = vec![0; k1.size() as usize];
|
||||
let len = k1.public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
|
||||
let len = k1
|
||||
.public_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
|
||||
.unwrap();
|
||||
assert_eq!(msg, &dmesg[..len]);
|
||||
}
|
||||
|
|
@ -807,7 +826,8 @@ mod test {
|
|||
let mut emesg = vec![0; k0.size() as usize];
|
||||
k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap();
|
||||
let mut dmesg = vec![0; k1.size() as usize];
|
||||
let len = k1.private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
|
||||
let len = k1
|
||||
.private_decrypt(&emesg, &mut dmesg, Padding::PKCS1)
|
||||
.unwrap();
|
||||
assert_eq!(msg, &dmesg[..len]);
|
||||
}
|
||||
|
|
@ -883,6 +903,6 @@ mod test {
|
|||
#[test]
|
||||
fn clone() {
|
||||
let key = Rsa::generate(2048).unwrap();
|
||||
key.clone();
|
||||
drop(key.clone());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,21 +63,24 @@
|
|||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::c_int;
|
||||
use std::io::{self, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use libc::c_int;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use hash::MessageDigest;
|
||||
use pkey::{HasPrivate, HasPublic, PKeyRef};
|
||||
use error::ErrorStack;
|
||||
use rsa::Padding;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new};
|
||||
} else {
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
}
|
||||
}
|
||||
|
||||
/// Salt lengths that must be used with `set_rsa_pss_saltlen`.
|
||||
pub struct RsaPssSaltlen(c_int);
|
||||
|
|
@ -459,7 +462,7 @@ impl<'a> Verifier<'a> {
|
|||
pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let r =
|
||||
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
|
||||
EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len());
|
||||
match r {
|
||||
1 => Ok(true),
|
||||
0 => {
|
||||
|
|
@ -501,12 +504,12 @@ mod test {
|
|||
use hex::{self, FromHex};
|
||||
use std::iter;
|
||||
|
||||
use hash::MessageDigest;
|
||||
use sign::{RsaPssSaltlen, Signer, Verifier};
|
||||
use ec::{EcGroup, EcKey};
|
||||
use hash::MessageDigest;
|
||||
use nid::Nid;
|
||||
use rsa::{Padding, Rsa};
|
||||
use pkey::PKey;
|
||||
use rsa::{Padding, Rsa};
|
||||
use sign::{RsaPssSaltlen, Signer, Verifier};
|
||||
|
||||
const INPUT: &'static str =
|
||||
"65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\
|
||||
|
|
@ -673,7 +676,7 @@ mod test {
|
|||
signer.update(data as &[u8]).unwrap();
|
||||
|
||||
let expected = vec![
|
||||
136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19
|
||||
136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19,
|
||||
];
|
||||
assert_eq!(signer.sign_to_vec().unwrap(), expected);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
use ffi::{
|
||||
self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO,
|
||||
BIO_CTRL_FLUSH,
|
||||
};
|
||||
use libc::{c_char, c_int, c_long, c_void, strlen};
|
||||
use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags, BIO_set_retry_read,
|
||||
BIO_set_retry_write};
|
||||
use std::any::Any;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
|
|
@ -19,11 +21,11 @@ pub struct StreamState<S> {
|
|||
}
|
||||
|
||||
/// Safe wrapper for BIO_METHOD
|
||||
pub struct BioMethod(compat::BIO_METHOD);
|
||||
pub struct BioMethod(BIO_METHOD);
|
||||
|
||||
impl BioMethod {
|
||||
fn new<S: Read + Write>() -> BioMethod {
|
||||
BioMethod(compat::BIO_METHOD::new::<S>())
|
||||
BioMethod(BIO_METHOD::new::<S>())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,8 +43,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta
|
|||
|
||||
unsafe {
|
||||
let bio = cvt_p(BIO_new(method.0.get()))?;
|
||||
compat::BIO_set_data(bio, Box::into_raw(state) as *mut _);
|
||||
compat::BIO_set_init(bio, 1);
|
||||
BIO_set_data(bio, Box::into_raw(state) as *mut _);
|
||||
BIO_set_init(bio, 1);
|
||||
|
||||
return Ok((bio, method));
|
||||
}
|
||||
|
|
@ -59,7 +61,7 @@ pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> {
|
|||
}
|
||||
|
||||
pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S {
|
||||
let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio));
|
||||
let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio));
|
||||
&state.stream
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +70,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S {
|
|||
}
|
||||
|
||||
unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> {
|
||||
&mut *(compat::BIO_get_data(bio) as *mut _)
|
||||
&mut *(BIO_get_data(bio) as *mut _)
|
||||
}
|
||||
|
||||
unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int {
|
||||
|
|
@ -117,8 +119,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int)
|
|||
|
||||
fn retriable_error(err: &io::Error) -> bool {
|
||||
match err.kind() {
|
||||
io::ErrorKind::WouldBlock |
|
||||
io::ErrorKind::NotConnected => true,
|
||||
io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -153,10 +154,10 @@ unsafe extern "C" fn ctrl<S: Write>(
|
|||
}
|
||||
|
||||
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());
|
||||
compat::BIO_set_flags(bio, 0);
|
||||
BIO_set_init(bio, 0);
|
||||
BIO_set_num(bio, 0);
|
||||
BIO_set_data(bio, ptr::null_mut());
|
||||
BIO_set_flags(bio, 0);
|
||||
1
|
||||
}
|
||||
|
||||
|
|
@ -165,44 +166,41 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int {
|
|||
return 0;
|
||||
}
|
||||
|
||||
let data = compat::BIO_get_data(bio);
|
||||
let data = BIO_get_data(bio);
|
||||
assert!(!data.is_null());
|
||||
Box::<StreamState<S>>::from_raw(data as *mut _);
|
||||
compat::BIO_set_data(bio, ptr::null_mut());
|
||||
compat::BIO_set_init(bio, 0);
|
||||
BIO_set_data(bio, ptr::null_mut());
|
||||
BIO_set_init(bio, 0);
|
||||
1
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use std::io::{Read, Write};
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init};
|
||||
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data};
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
||||
|
||||
pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {}
|
||||
|
||||
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
#[allow(bad_style)]
|
||||
struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
|
||||
impl BIO_METHOD {
|
||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
unsafe {
|
||||
let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _);
|
||||
assert!(!ptr.is_null());
|
||||
let ret = BIO_METHOD(ptr);
|
||||
assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0);
|
||||
assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0);
|
||||
assert!(ffi::BIO_meth_set_create(ptr, create) != 0);
|
||||
assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
@ -214,37 +212,29 @@ mod compat {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use ffi;
|
||||
use libc::{c_int, c_void};
|
||||
|
||||
pub struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
struct BIO_METHOD(*mut ffi::BIO_METHOD);
|
||||
|
||||
impl BIO_METHOD {
|
||||
pub fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
fn new<S: Read + Write>() -> BIO_METHOD {
|
||||
let ptr = Box::new(ffi::BIO_METHOD {
|
||||
type_: ffi::BIO_TYPE_NONE,
|
||||
name: b"rust\0".as_ptr() as *const _,
|
||||
bwrite: Some(super::bwrite::<S>),
|
||||
bread: Some(super::bread::<S>),
|
||||
bputs: Some(super::bputs::<S>),
|
||||
bwrite: Some(bwrite::<S>),
|
||||
bread: Some(bread::<S>),
|
||||
bputs: Some(bputs::<S>),
|
||||
bgets: None,
|
||||
ctrl: Some(super::ctrl::<S>),
|
||||
create: Some(super::create),
|
||||
destroy: Some(super::destroy::<S>),
|
||||
ctrl: Some(ctrl::<S>),
|
||||
create: Some(create),
|
||||
destroy: Some(destroy::<S>),
|
||||
callback_ctrl: None,
|
||||
});
|
||||
|
||||
BIO_METHOD(Box::into_raw(ptr))
|
||||
}
|
||||
|
||||
pub fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
fn get(&self) -> *mut ffi::BIO_METHOD {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
@ -257,23 +247,29 @@ mod compat {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) {
|
||||
(*bio).init = init;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) {
|
||||
(*bio).flags = flags;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void {
|
||||
(*bio).ptr
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) {
|
||||
(*bio).ptr = data;
|
||||
}
|
||||
|
||||
pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) {
|
||||
(*bio).num = num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
use ffi;
|
||||
use foreign_types::ForeignType;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
use libc::c_char;
|
||||
#[cfg(ossl111)]
|
||||
use libc::size_t;
|
||||
use libc::{c_char, c_int, c_uchar, c_uint, c_void};
|
||||
use libc::{c_int, c_uchar, c_uint, c_void};
|
||||
#[cfg(not(osslconf = "OPENSSL_NO_PSK"))]
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
|
@ -13,11 +16,11 @@ use std::str;
|
|||
use std::sync::Arc;
|
||||
|
||||
use dh::Dh;
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
use ec::EcKey;
|
||||
use error::ErrorStack;
|
||||
use pkey::Params;
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
use ssl::AlpnError;
|
||||
#[cfg(ossl111)]
|
||||
use ssl::ExtensionContext;
|
||||
|
|
@ -37,7 +40,8 @@ where
|
|||
|
||||
// raw pointer shenanigans to break the borrow of ctx
|
||||
// the callback can't mess with its own ex_data slot so this is safe
|
||||
let verify = ctx.ex_data(ssl_idx)
|
||||
let verify = ctx
|
||||
.ex_data(ssl_idx)
|
||||
.expect("BUG: store context missing ssl")
|
||||
.ssl_context()
|
||||
.ex_data(verify_idx)
|
||||
|
|
@ -66,7 +70,8 @@ where
|
|||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback_idx = SslContext::cached_ex_index::<F>();
|
||||
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(callback_idx)
|
||||
.expect("BUG: psk callback missing") as *const F;
|
||||
let hint = if hint != ptr::null() {
|
||||
|
|
@ -130,7 +135,8 @@ where
|
|||
let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing");
|
||||
let callback_idx = Ssl::cached_ex_index::<Arc<F>>();
|
||||
|
||||
let callback = ctx.ex_data(ssl_idx)
|
||||
let callback = ctx
|
||||
.ex_data(ssl_idx)
|
||||
.expect("BUG: store context missing ssl")
|
||||
.ex_data(callback_idx)
|
||||
.expect("BUG: ssl verify callback missing")
|
||||
|
|
@ -146,7 +152,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: sni callback missing") as *const F;
|
||||
let mut alert = SslAlert(*al);
|
||||
|
|
@ -160,7 +167,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub extern "C" fn raw_alpn_select<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
out: *mut *const c_uchar,
|
||||
|
|
@ -174,7 +181,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: alpn callback missing") as *const F;
|
||||
let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize);
|
||||
|
|
@ -199,7 +207,8 @@ where
|
|||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: tmp dh callback missing") as *const F;
|
||||
|
||||
|
|
@ -216,7 +225,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
pub unsafe extern "C" fn raw_tmp_ecdh<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
is_export: c_int,
|
||||
|
|
@ -226,7 +235,8 @@ where
|
|||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: tmp ecdh callback missing") as *const F;
|
||||
|
||||
|
|
@ -252,7 +262,8 @@ where
|
|||
F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
let callback = ssl
|
||||
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
.expect("BUG: ssl tmp dh callback missing")
|
||||
.clone();
|
||||
|
||||
|
|
@ -269,7 +280,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>(
|
||||
ssl: *mut ffi::SSL,
|
||||
is_export: c_int,
|
||||
|
|
@ -279,7 +290,8 @@ where
|
|||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
let callback = ssl
|
||||
.ex_data(Ssl::cached_ex_index::<Arc<F>>())
|
||||
.expect("BUG: ssl tmp ecdh callback missing")
|
||||
.clone();
|
||||
|
||||
|
|
@ -301,7 +313,8 @@ where
|
|||
F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: ocsp callback missing") as *const F;
|
||||
let ret = (*callback)(ssl);
|
||||
|
|
@ -335,7 +348,8 @@ where
|
|||
F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: new session callback missing") as *const F;
|
||||
let session = SslSession::from_ptr(session);
|
||||
|
|
@ -353,7 +367,8 @@ pub unsafe extern "C" fn raw_remove_session<F>(
|
|||
F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send,
|
||||
{
|
||||
let ctx = SslContextRef::from_ptr(ctx);
|
||||
let callback = ctx.ex_data(SslContext::cached_ex_index::<F>())
|
||||
let callback = ctx
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: remove session callback missing");
|
||||
let session = SslSessionRef::from_ptr(session);
|
||||
|
||||
|
|
@ -375,7 +390,8 @@ where
|
|||
F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: get session callback missing") as *const F;
|
||||
let data = slice::from_raw_parts(data as *const u8, len as usize);
|
||||
|
|
@ -397,7 +413,8 @@ where
|
|||
F: Fn(&SslRef, &str) + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr(ssl as *mut _);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: get session callback missing");
|
||||
let line = CStr::from_ptr(line).to_bytes();
|
||||
|
|
@ -416,7 +433,8 @@ where
|
|||
F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: stateless cookie generate callback missing") as *const F;
|
||||
let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize);
|
||||
|
|
@ -442,7 +460,8 @@ where
|
|||
F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send,
|
||||
{
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: stateless cookie verify callback missing") as *const F;
|
||||
let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize);
|
||||
|
|
@ -459,7 +478,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: cookie generate callback missing") as *const F;
|
||||
// We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for
|
||||
|
|
@ -495,7 +515,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: cookie verify callback missing") as *const F;
|
||||
let slice =
|
||||
|
|
@ -528,7 +549,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: custom ext add callback missing") as *const F;
|
||||
let ectx = ExtensionContext::from_bits_truncate(context);
|
||||
|
|
@ -604,7 +626,8 @@ where
|
|||
{
|
||||
unsafe {
|
||||
let ssl = SslRef::from_ptr_mut(ssl);
|
||||
let callback = ssl.ssl_context()
|
||||
let callback = ssl
|
||||
.ssl_context()
|
||||
.ex_data(SslContext::cached_ex_index::<F>())
|
||||
.expect("BUG: custom ext parse callback missing") as *const F;
|
||||
let ectx = ExtensionContext::from_bits_truncate(context);
|
||||
|
|
|
|||
|
|
@ -3,16 +3,22 @@ use std::ops::{Deref, DerefMut};
|
|||
|
||||
use dh::Dh;
|
||||
use error::ErrorStack;
|
||||
use ssl::{HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions,
|
||||
SslRef, SslStream, SslVerifyMode};
|
||||
use ssl::{
|
||||
HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef,
|
||||
SslStream, SslVerifyMode,
|
||||
};
|
||||
use version;
|
||||
|
||||
fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
|
||||
let mut ctx = SslContextBuilder::new(method)?;
|
||||
|
||||
let mut opts = SslOptions::ALL | SslOptions::NO_COMPRESSION | SslOptions::NO_SSLV2
|
||||
| SslOptions::NO_SSLV3 | SslOptions::SINGLE_DH_USE
|
||||
| SslOptions::SINGLE_ECDH_USE | SslOptions::CIPHER_SERVER_PREFERENCE;
|
||||
let mut opts = SslOptions::ALL
|
||||
| SslOptions::NO_COMPRESSION
|
||||
| SslOptions::NO_SSLV2
|
||||
| SslOptions::NO_SSLV3
|
||||
| SslOptions::SINGLE_DH_USE
|
||||
| SslOptions::SINGLE_ECDH_USE
|
||||
| SslOptions::CIPHER_SERVER_PREFERENCE;
|
||||
opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
|
||||
ctx.set_options(opts);
|
||||
|
|
@ -23,7 +29,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
|
|||
// This is quite a useful optimization for saving memory, but historically
|
||||
// caused CVEs in OpenSSL pre-1.0.1h, according to
|
||||
// https://bugs.python.org/issue25672
|
||||
if version::number() >= 0x1000108f {
|
||||
if version::number() >= 0x1_00_01_08_0 {
|
||||
mode |= SslMode::RELEASE_BUFFERS;
|
||||
}
|
||||
|
||||
|
|
@ -277,37 +283,33 @@ impl DerefMut for SslAcceptorBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
Ok(())
|
||||
}
|
||||
} else if #[cfg(any(ossl102, libressl))] {
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
ctx.set_ecdh_auto(true)
|
||||
}
|
||||
} else {
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
|
||||
let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?;
|
||||
ctx.set_tmp_ecdh(&curve)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl102)]
|
||||
fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
ctx.set_ecdh_auto(true)
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl102, libressl261))] {
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify(SslVerifyMode::PEER);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
|
||||
}
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> {
|
||||
use x509::verify::X509CheckFlags;
|
||||
|
||||
let param = ssl.param_mut();
|
||||
|
|
@ -316,26 +318,30 @@ fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack>
|
|||
Ok(ip) => param.set_ip(ip),
|
||||
Err(_) => param.set_host(domain),
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fn setup_verify(ctx: &mut SslContextBuilder) {
|
||||
ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback);
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> {
|
||||
let domain = domain.to_string();
|
||||
ssl.set_ex_data(*verify::HOSTNAME_IDX, domain);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl101)]
|
||||
mod verify {
|
||||
mod verify {
|
||||
use std::net::IpAddr;
|
||||
use std::str;
|
||||
|
||||
use ex_data::Index;
|
||||
use nid::Nid;
|
||||
use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
|
||||
X509VerifyResult};
|
||||
use stack::Stack;
|
||||
use ssl::Ssl;
|
||||
use stack::Stack;
|
||||
use x509::{
|
||||
GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef,
|
||||
X509VerifyResult,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap();
|
||||
|
|
@ -499,4 +505,6 @@ mod verify {
|
|||
IpAddr::V6(ref addr) => actual == addr.octets(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,17 +99,18 @@ impl fmt::Display for Error {
|
|||
Some(_) => fmt.write_str("a nonblocking read call would have blocked"),
|
||||
None => fmt.write_str("the operation should be retried"),
|
||||
},
|
||||
ErrorCode::WANT_WRITE => match self.io_error() {
|
||||
Some(_) => fmt.write_str("a nonblocking write call would have blocked"),
|
||||
None => fmt.write_str("the operation should be retried"),
|
||||
},
|
||||
ErrorCode::SYSCALL => match self.io_error() {
|
||||
Some(err) => write!(fmt, "the inner stream returned an error: {}", err),
|
||||
Some(err) => write!(fmt, "{}", err),
|
||||
None => fmt.write_str("unexpected EOF"),
|
||||
},
|
||||
ErrorCode::SSL => {
|
||||
fmt.write_str("OpenSSL error")?;
|
||||
if let Some(ref err) = self.ssl_error() {
|
||||
write!(fmt, ": {}", err)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
ErrorCode::SSL => match self.ssl_error() {
|
||||
Some(e) => write!(fmt, "{}", e),
|
||||
None => fmt.write_str("OpenSSL error"),
|
||||
},
|
||||
ErrorCode(code) => write!(fmt, "unknown error code {}", code),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,23 +78,24 @@ use std::str;
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use dh::{Dh, DhRef};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
use ec::EcKey;
|
||||
use ec::EcKeyRef;
|
||||
use error::ErrorStack;
|
||||
use ex_data::Index;
|
||||
#[cfg(ossl111)]
|
||||
use hash::MessageDigest;
|
||||
#[cfg(ossl110)]
|
||||
use nid::Nid;
|
||||
use pkey::{HasPrivate, PKeyRef, Params, Private};
|
||||
use ssl::bio::BioMethod;
|
||||
use ssl::callbacks::*;
|
||||
use ssl::error::InnerError;
|
||||
use stack::{Stack, StackRef};
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(ossl102)]
|
||||
use x509::store::X509Store;
|
||||
use x509::store::{X509StoreBuilderRef, X509StoreRef};
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
use x509::verify::X509VerifyParamRef;
|
||||
use x509::{X509, X509Name, X509Ref, X509StoreContextRef, X509VerifyResult};
|
||||
use {cvt, cvt_n, cvt_p, init};
|
||||
|
|
@ -284,7 +285,7 @@ impl SslMethod {
|
|||
/// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method`
|
||||
/// on OpenSSL 1.0.x.
|
||||
pub fn tls() -> SslMethod {
|
||||
SslMethod(compat::tls_method())
|
||||
unsafe { SslMethod(TLS_method()) }
|
||||
}
|
||||
|
||||
/// Support all versions of the DTLS protocol.
|
||||
|
|
@ -292,7 +293,7 @@ impl SslMethod {
|
|||
/// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method`
|
||||
/// on OpenSSL 1.0.x.
|
||||
pub fn dtls() -> SslMethod {
|
||||
SslMethod(compat::dtls_method())
|
||||
unsafe { SslMethod(DTLS_method()) }
|
||||
}
|
||||
|
||||
/// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value.
|
||||
|
|
@ -506,12 +507,12 @@ impl SslAlert {
|
|||
|
||||
/// An error returned from an ALPN selection callback.
|
||||
///
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct AlpnError(c_int);
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
impl AlpnError {
|
||||
/// Terminate the handshake with a fatal alert.
|
||||
///
|
||||
|
|
@ -767,7 +768,7 @@ impl SslContextBuilder {
|
|||
/// Requires OpenSSL 1.0.1 or 1.0.2.
|
||||
///
|
||||
/// This corresponds to `SSL_CTX_set_tmp_ecdh_callback`.
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
|
|
@ -976,7 +977,7 @@ impl SslContextBuilder {
|
|||
/// This corresponds to [`SSL_CTX_set_ecdh_auto`].
|
||||
///
|
||||
/// [`SSL_CTX_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_ecdh_auto.html
|
||||
#[cfg(any(ossl102, libressl))]
|
||||
#[cfg(any(libressl, all(ossl102, not(ossl110))))]
|
||||
pub 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(|_| ()) }
|
||||
}
|
||||
|
|
@ -992,7 +993,7 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
|
||||
pub fn set_options(&mut self, option: SslOptions) -> SslOptions {
|
||||
let bits = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
|
||||
let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) };
|
||||
SslOptions { bits }
|
||||
}
|
||||
|
||||
|
|
@ -1002,7 +1003,7 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
|
||||
pub fn options(&self) -> SslOptions {
|
||||
let bits = unsafe { compat::SSL_CTX_get_options(self.as_ptr()) };
|
||||
let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) };
|
||||
SslOptions { bits }
|
||||
}
|
||||
|
||||
|
|
@ -1012,7 +1013,7 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
|
||||
pub fn clear_options(&mut self, option: SslOptions) -> SslOptions {
|
||||
let bits = unsafe { compat::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
|
||||
let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) };
|
||||
SslOptions { bits }
|
||||
}
|
||||
|
||||
|
|
@ -1023,15 +1024,15 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_set_min_proto_version`].
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0 or newer.
|
||||
/// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer.
|
||||
///
|
||||
/// [`SSL_CTX_set_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
|
||||
#[cfg(any(ossl110))]
|
||||
#[cfg(any(ossl110, libressl261))]
|
||||
pub fn set_min_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::SSL_CTX_set_min_proto_version(
|
||||
self.as_ptr(),
|
||||
version.map_or(0, |v| v.0),
|
||||
version.map_or(0, |v| v.0 as _),
|
||||
)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
|
@ -1043,15 +1044,15 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_set_max_proto_version`].
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0 or newer.
|
||||
/// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer.
|
||||
///
|
||||
/// [`SSL_CTX_set_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
|
||||
#[cfg(any(ossl110))]
|
||||
#[cfg(any(ossl110, libressl261))]
|
||||
pub fn set_max_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::SSL_CTX_set_max_proto_version(
|
||||
self.as_ptr(),
|
||||
version.map_or(0, |v| v.0),
|
||||
version.map_or(0, |v| v.0 as _),
|
||||
)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
|
@ -1063,10 +1064,10 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_get_min_proto_version`].
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0g or newer.
|
||||
/// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
|
||||
///
|
||||
/// [`SSL_CTX_get_min_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
|
||||
#[cfg(any(ossl110g))]
|
||||
#[cfg(any(ossl110g, libressl270))]
|
||||
pub fn min_proto_version(&mut self) -> Option<SslVersion> {
|
||||
unsafe {
|
||||
let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr());
|
||||
|
|
@ -1085,10 +1086,10 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_get_max_proto_version`].
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0g or newer.
|
||||
/// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer.
|
||||
///
|
||||
/// [`SSL_CTX_get_max_proto_version`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_min_proto_version.html
|
||||
#[cfg(any(ossl110g))]
|
||||
#[cfg(any(ossl110g, libressl270))]
|
||||
pub fn max_proto_version(&mut self) -> Option<SslVersion> {
|
||||
unsafe {
|
||||
let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr());
|
||||
|
|
@ -1109,10 +1110,10 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_set_alpn_protos`].
|
||||
///
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
|
||||
///
|
||||
/// [`SSL_CTX_set_alpn_protos`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_alpn_protos.html
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
assert!(protocols.len() <= c_uint::max_value() as usize);
|
||||
|
|
@ -1140,12 +1141,12 @@ impl SslContextBuilder {
|
|||
///
|
||||
/// This corresponds to [`SSL_CTX_set_alpn_select_cb`].
|
||||
///
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
|
||||
///
|
||||
/// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos
|
||||
/// [`select_next_proto`]: fn.select_next_proto.html
|
||||
/// [`SSL_CTX_set_alpn_select_cb`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_alpn_protos.html
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn set_alpn_select_callback<F>(&mut self, callback: F)
|
||||
where
|
||||
F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send,
|
||||
|
|
@ -1512,6 +1513,24 @@ impl SslContextBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the maximum amount of early data that will be accepted on incoming connections.
|
||||
///
|
||||
/// Defaults to 0.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_set_max_early_data`].
|
||||
///
|
||||
/// [`SSL_CTX_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_max_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
|
||||
if unsafe { ffi::SSL_CTX_set_max_early_data(self.as_ptr(), bytes) } == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes the builder, returning a new `SslContext`.
|
||||
pub fn build(self) -> SslContext {
|
||||
self.0
|
||||
|
|
@ -1537,7 +1556,7 @@ foreign_type_and_impl_send_sync! {
|
|||
impl Clone for SslContext {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
compat::SSL_CTX_up_ref(self.as_ptr());
|
||||
SSL_CTX_up_ref(self.as_ptr());
|
||||
SslContext::from_ptr(self.as_ptr())
|
||||
}
|
||||
}
|
||||
|
|
@ -1570,7 +1589,7 @@ impl SslContext {
|
|||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let idx = cvt_n(compat::get_new_idx(free_data_box::<T>))?;
|
||||
let idx = cvt_n(get_new_idx(free_data_box::<T>))?;
|
||||
Ok(Index::from_raw(idx))
|
||||
}
|
||||
}
|
||||
|
|
@ -1666,6 +1685,18 @@ impl SslContextRef {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the maximum amount of early data that will be accepted on incoming connections.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_CTX_get_max_early_data`].
|
||||
///
|
||||
/// [`SSL_CTX_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_get_max_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn max_early_data(&self) -> u32 {
|
||||
unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the state of a cipher.
|
||||
|
|
@ -1814,7 +1845,7 @@ impl SslCipherRef {
|
|||
}
|
||||
}
|
||||
|
||||
foreign_type! {
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::SSL_SESSION;
|
||||
fn drop = ffi::SSL_SESSION_free;
|
||||
|
||||
|
|
@ -1829,9 +1860,6 @@ foreign_type! {
|
|||
pub struct SslSessionRef;
|
||||
}
|
||||
|
||||
unsafe impl Sync for SslSession {}
|
||||
unsafe impl Send for SslSession {}
|
||||
|
||||
impl Clone for SslSession {
|
||||
fn clone(&self) -> SslSession {
|
||||
SslSessionRef::to_owned(self)
|
||||
|
|
@ -1856,7 +1884,7 @@ impl ToOwned for SslSessionRef {
|
|||
|
||||
fn to_owned(&self) -> SslSession {
|
||||
unsafe {
|
||||
compat::SSL_SESSION_up_ref(self.as_ptr());
|
||||
SSL_SESSION_up_ref(self.as_ptr());
|
||||
SslSession(self.as_ptr())
|
||||
}
|
||||
}
|
||||
|
|
@ -1882,7 +1910,7 @@ impl SslSessionRef {
|
|||
///
|
||||
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
|
||||
pub fn master_key_len(&self) -> usize {
|
||||
unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
|
||||
unsafe { SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) }
|
||||
}
|
||||
|
||||
/// Copies the master key into the provided buffer.
|
||||
|
|
@ -1893,7 +1921,19 @@ impl SslSessionRef {
|
|||
///
|
||||
/// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html
|
||||
pub fn master_key(&self, buf: &mut [u8]) -> usize {
|
||||
unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
|
||||
unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
|
||||
}
|
||||
|
||||
/// Gets the maximum amount of early data that can be sent on this session.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_SESSION_get_max_early_data`].
|
||||
///
|
||||
/// [`SSL_SESSION_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_max_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn max_early_data(&self) -> u32 {
|
||||
unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) }
|
||||
}
|
||||
|
||||
to_der! {
|
||||
|
|
@ -1907,7 +1947,7 @@ impl SslSessionRef {
|
|||
}
|
||||
}
|
||||
|
||||
foreign_type! {
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::SSL;
|
||||
fn drop = ffi::SSL_free;
|
||||
|
||||
|
|
@ -1925,9 +1965,6 @@ foreign_type! {
|
|||
pub struct SslRef;
|
||||
}
|
||||
|
||||
unsafe impl Sync for Ssl {}
|
||||
unsafe impl Send for Ssl {}
|
||||
|
||||
impl fmt::Debug for Ssl {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(&**self, fmt)
|
||||
|
|
@ -1949,7 +1986,7 @@ impl Ssl {
|
|||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let idx = cvt_n(compat::get_new_ssl_idx(free_data_box::<T>))?;
|
||||
let idx = cvt_n(get_new_ssl_idx(free_data_box::<T>))?;
|
||||
Ok(Index::from_raw(idx))
|
||||
}
|
||||
}
|
||||
|
|
@ -2114,7 +2151,7 @@ impl SslRef {
|
|||
/// This corresponds to `SSL_set_tmp_ecdh_callback`.
|
||||
///
|
||||
/// [`SslContextBuilder::set_tmp_ecdh_callback`]: struct.SslContextBuilder.html#method.set_tmp_ecdh_callback
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
#[cfg(any(all(ossl101, not(ossl110))))]
|
||||
pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F)
|
||||
where
|
||||
F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send,
|
||||
|
|
@ -2134,7 +2171,7 @@ impl SslRef {
|
|||
///
|
||||
/// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh
|
||||
/// [`SSL_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_ecdh_auto.html
|
||||
#[cfg(ossl102)]
|
||||
#[cfg(all(ossl102, not(ossl110)))]
|
||||
pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) }
|
||||
}
|
||||
|
|
@ -2234,6 +2271,30 @@ impl SslRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the verified certificate chani of the peer, including the leaf certificate.
|
||||
///
|
||||
/// If verification was not successful (i.e. [`verify_result`] does not return
|
||||
/// [`X509VerifyResult::OK`]), this chain may be incomplete or invalid.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.0 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_get0_verified_chain`].
|
||||
///
|
||||
/// [`verify_result`]: #method.verify_result
|
||||
/// [`X509VerifyResult::OK`]: ../x509/struct.X509VerifyResult.html#associatedconstant.OK
|
||||
/// [`SSL_get0_verified_chain`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_get0_verified_chain.html
|
||||
#[cfg(ossl110)]
|
||||
pub fn verified_chain(&self) -> Option<&StackRef<X509>> {
|
||||
unsafe {
|
||||
let ptr = ffi::SSL_get0_verified_chain(self.as_ptr());
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(StackRef::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Like [`SslContext::certificate`].
|
||||
///
|
||||
/// This corresponds to `SSL_get_certificate`.
|
||||
|
|
@ -2306,12 +2367,12 @@ impl SslRef {
|
|||
/// The protocol's name is returned is an opaque sequence of bytes. It is up to the client
|
||||
/// to interpret it.
|
||||
///
|
||||
/// Requires OpenSSL 1.0.2 or newer.
|
||||
/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_get0_alpn_selected`].
|
||||
///
|
||||
/// [`SSL_get0_alpn_selected`]: https://www.openssl.org/docs/manmaster/man3/SSL_get0_next_proto_negotiated.html
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn selected_alpn_protocol(&self) -> Option<&[u8]> {
|
||||
unsafe {
|
||||
let mut data: *const c_uchar = ptr::null();
|
||||
|
|
@ -2346,14 +2407,38 @@ impl SslRef {
|
|||
///
|
||||
/// This corresponds to [`SSL_get_servername`].
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// While the SNI specification requires that servernames be valid domain names (and therefore
|
||||
/// ASCII), OpenSSL does not enforce this restriction. If the servername provided by the client
|
||||
/// is not valid UTF-8, this function will return `None`. The `servername_raw` method returns
|
||||
/// the raw bytes and does not have this restriction.
|
||||
///
|
||||
/// [`SSL_get_servername`]: https://www.openssl.org/docs/manmaster/man3/SSL_get_servername.html
|
||||
// FIXME maybe rethink in 0.11?
|
||||
pub fn servername(&self, type_: NameType) -> Option<&str> {
|
||||
self.servername_raw(type_)
|
||||
.and_then(|b| str::from_utf8(b).ok())
|
||||
}
|
||||
|
||||
/// Returns the servername sent by the client via Server Name Indication (SNI).
|
||||
///
|
||||
/// It is only useful on the server side.
|
||||
///
|
||||
/// This corresponds to [`SSL_get_servername`].
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// Unlike `servername`, this method does not require the name be valid UTF-8.
|
||||
///
|
||||
/// [`SSL_get_servername`]: https://www.openssl.org/docs/manmaster/man3/SSL_get_servername.html
|
||||
pub fn servername_raw(&self, type_: NameType) -> Option<&[u8]> {
|
||||
unsafe {
|
||||
let name = ffi::SSL_get_servername(self.as_ptr(), type_.0);
|
||||
if name == ptr::null() {
|
||||
None
|
||||
} else {
|
||||
Some(str::from_utf8(CStr::from_ptr(name as *const _).to_bytes()).unwrap())
|
||||
Some(CStr::from_ptr(name as *const _).to_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2386,7 +2471,7 @@ impl SslRef {
|
|||
/// This corresponds to [`SSL_get0_param`].
|
||||
///
|
||||
/// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
|
||||
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
|
||||
}
|
||||
|
|
@ -2479,6 +2564,36 @@ impl SslRef {
|
|||
}
|
||||
}
|
||||
|
||||
/// Derives keying material for application use in accordance to RFC 5705.
|
||||
///
|
||||
/// This function is only usable with TLSv1.3, wherein there is no distinction between an empty context and no
|
||||
/// context. Therefore, unlike `export_keying_material`, `context` must always be supplied.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_export_keying_material_early`].
|
||||
///
|
||||
/// [`SSL_export_keying_material_early`]: https://www.openssl.org/docs/manmaster/man3/SSL_export_keying_material_early.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn export_keying_material_early(
|
||||
&self,
|
||||
out: &mut [u8],
|
||||
label: &str,
|
||||
context: &[u8],
|
||||
) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::SSL_export_keying_material_early(
|
||||
self.as_ptr(),
|
||||
out.as_mut_ptr() as *mut c_uchar,
|
||||
out.len(),
|
||||
label.as_ptr() as *const c_char,
|
||||
label.len(),
|
||||
context.as_ptr() as *const c_uchar,
|
||||
context.len(),
|
||||
)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the session to be used.
|
||||
///
|
||||
/// This should be called before the handshake to attempt to reuse a previously established
|
||||
|
|
@ -2564,7 +2679,7 @@ impl SslRef {
|
|||
///
|
||||
/// [`SSL_is_server`]: https://www.openssl.org/docs/manmaster/man3/SSL_is_server.html
|
||||
pub fn is_server(&self) -> bool {
|
||||
unsafe { compat::SSL_is_server(self.as_ptr()) != 0 }
|
||||
unsafe { SSL_is_server(self.as_ptr()) != 0 }
|
||||
}
|
||||
|
||||
/// Sets the extra data at the specified index.
|
||||
|
|
@ -2617,6 +2732,57 @@ impl SslRef {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the maximum amount of early data that will be accepted on this connection.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_set_max_early_data`].
|
||||
///
|
||||
/// [`SSL_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_max_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
|
||||
if unsafe { ffi::SSL_set_max_early_data(self.as_ptr(), bytes) } == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the maximum amount of early data that can be sent on this connection.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_get_max_early_data`].
|
||||
///
|
||||
/// [`SSL_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_max_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn max_early_data(&self) -> u32 {
|
||||
unsafe { ffi::SSL_get_max_early_data(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Copies the contents of the last Finished message sent to the peer into the provided buffer.
|
||||
///
|
||||
/// The total size of the message is returned, so this can be used to determine the size of the
|
||||
/// buffer required.
|
||||
///
|
||||
/// This corresponds to `SSL_get_finished`.
|
||||
pub fn finished(&self, buf: &mut [u8]) -> usize {
|
||||
unsafe { ffi::SSL_get_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len()) }
|
||||
}
|
||||
|
||||
/// Copies the contents of the last Finished message received from the peer into the provided
|
||||
/// buffer.
|
||||
///
|
||||
/// The total size of the message is returned, so this can be used to determine the size of the
|
||||
/// buffer required.
|
||||
///
|
||||
/// This corresponds to `SSL_get_finished`.
|
||||
pub fn peer_finished(&self, buf: &mut [u8]) -> usize {
|
||||
unsafe {
|
||||
ffi::SSL_get_peer_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An SSL stream midway through the handshake process.
|
||||
|
|
@ -2860,7 +3026,8 @@ impl<S: Read + Write> Read for SslStream<S> {
|
|||
}
|
||||
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
|
||||
Err(e) => {
|
||||
return Err(e.into_io_error()
|
||||
return Err(e
|
||||
.into_io_error()
|
||||
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
|
||||
}
|
||||
}
|
||||
|
|
@ -2875,7 +3042,8 @@ impl<S: Read + Write> Write for SslStream<S> {
|
|||
Ok(n) => return Ok(n),
|
||||
Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {}
|
||||
Err(e) => {
|
||||
return Err(e.into_io_error()
|
||||
return Err(e
|
||||
.into_io_error()
|
||||
.unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))
|
||||
}
|
||||
}
|
||||
|
|
@ -2927,6 +3095,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Configure as an outgoing stream from a client.
|
||||
///
|
||||
/// This corresponds to [`SSL_set_connect_state`].
|
||||
///
|
||||
/// [`SSL_set_connect_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html
|
||||
pub fn set_connect_state(&mut self) {
|
||||
unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Configure as an incoming stream to a server.
|
||||
///
|
||||
/// This corresponds to [`SSL_set_accept_state`].
|
||||
///
|
||||
/// [`SSL_set_accept_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_accept_state.html
|
||||
pub fn set_accept_state(&mut self) {
|
||||
unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) }
|
||||
}
|
||||
|
||||
/// See `Ssl::connect`
|
||||
pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> {
|
||||
let mut stream = self.inner;
|
||||
|
|
@ -2967,7 +3153,91 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// Future work: early IO methods
|
||||
/// Initiates the handshake.
|
||||
///
|
||||
/// This will fail if `set_accept_state` or `set_connect_state` was not called first.
|
||||
///
|
||||
/// This corresponds to [`SSL_do_handshake`].
|
||||
///
|
||||
/// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html
|
||||
pub fn handshake(self) -> Result<SslStream<S>, HandshakeError<S>> {
|
||||
let mut stream = self.inner;
|
||||
let ret = unsafe { ffi::SSL_do_handshake(stream.ssl.as_ptr()) };
|
||||
if ret > 0 {
|
||||
Ok(stream)
|
||||
} else {
|
||||
let error = stream.make_error(ret);
|
||||
match error.code() {
|
||||
ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => Err(HandshakeError::WouldBlock(
|
||||
MidHandshakeSslStream { stream, error },
|
||||
)),
|
||||
_ => Err(HandshakeError::Failure(MidHandshakeSslStream {
|
||||
stream,
|
||||
error,
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read application data transmitted by a client before handshake
|
||||
/// completion.
|
||||
///
|
||||
/// Useful for reducing latency, but vulnerable to replay attacks. Call
|
||||
/// `set_accept_state` first.
|
||||
///
|
||||
/// Returns `Ok(0)` if all early data has been read.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_read_early_data`].
|
||||
///
|
||||
/// [`SSL_read_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_read_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
let mut read = 0;
|
||||
let ret = unsafe {
|
||||
ffi::SSL_read_early_data(
|
||||
self.inner.ssl.as_ptr(),
|
||||
buf.as_ptr() as *mut c_void,
|
||||
buf.len(),
|
||||
&mut read,
|
||||
)
|
||||
};
|
||||
match ret {
|
||||
ffi::SSL_READ_EARLY_DATA_ERROR => Err(self.inner.make_error(ret)),
|
||||
ffi::SSL_READ_EARLY_DATA_SUCCESS => Ok(read),
|
||||
ffi::SSL_READ_EARLY_DATA_FINISH => Ok(0),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Send data to the server without blocking on handshake completion.
|
||||
///
|
||||
/// Useful for reducing latency, but vulnerable to replay attacks. Call
|
||||
/// `set_connect_state` first.
|
||||
///
|
||||
/// Requires OpenSSL 1.1.1 or newer.
|
||||
///
|
||||
/// This corresponds to [`SSL_write_early_data`].
|
||||
///
|
||||
/// [`SSL_write_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_write_early_data.html
|
||||
#[cfg(ossl111)]
|
||||
pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> {
|
||||
let mut written = 0;
|
||||
let ret = unsafe {
|
||||
ffi::SSL_write_early_data(
|
||||
self.inner.ssl.as_ptr(),
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len(),
|
||||
&mut written,
|
||||
)
|
||||
};
|
||||
if ret > 0 {
|
||||
Ok(written as usize)
|
||||
} else {
|
||||
Err(self.inner.make_error(ret))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> SslStreamBuilder<S> {
|
||||
|
|
@ -3008,16 +3278,11 @@ pub enum ShutdownResult {
|
|||
Received,
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
|
||||
pub use ffi::{
|
||||
SSL_CTX_clear_options, SSL_CTX_get_options, SSL_CTX_set_options, SSL_CTX_up_ref,
|
||||
SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server,
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
SSL_CTX_up_ref,
|
||||
SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, TLS_method, DTLS_method,
|
||||
};
|
||||
|
||||
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
|
||||
|
|
@ -3041,45 +3306,8 @@ mod compat {
|
|||
Some(f),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn tls_method() -> *const ffi::SSL_METHOD {
|
||||
unsafe { ffi::TLS_method() }
|
||||
}
|
||||
|
||||
pub fn dtls_method() -> *const ffi::SSL_METHOD {
|
||||
unsafe { ffi::DTLS_method() }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use std::ptr;
|
||||
|
||||
use ffi;
|
||||
use libc::{self, c_int, c_long, c_uchar, c_ulong, size_t};
|
||||
|
||||
pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong {
|
||||
ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
} else {
|
||||
use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method};
|
||||
|
||||
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
|
||||
ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
|
||||
|
|
@ -3089,52 +3317,49 @@ mod compat {
|
|||
ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f))
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int {
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> 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,
|
||||
line!() as c_int,
|
||||
);
|
||||
0
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn SSL_SESSION_get_master_key(
|
||||
session: *const ffi::SSL_SESSION,
|
||||
out: *mut c_uchar,
|
||||
mut outlen: size_t,
|
||||
) -> size_t {
|
||||
mut outlen: usize,
|
||||
) -> usize {
|
||||
if outlen == 0 {
|
||||
return (*session).master_key_length as size_t;
|
||||
return (*session).master_key_length as usize;
|
||||
}
|
||||
if outlen > (*session).master_key_length as size_t {
|
||||
outlen = (*session).master_key_length as size_t;
|
||||
if outlen > (*session).master_key_length as usize {
|
||||
outlen = (*session).master_key_length as usize;
|
||||
}
|
||||
ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen);
|
||||
outlen
|
||||
}
|
||||
|
||||
pub fn tls_method() -> *const ffi::SSL_METHOD {
|
||||
unsafe { ffi::SSLv23_method() }
|
||||
}
|
||||
|
||||
pub fn dtls_method() -> *const ffi::SSL_METHOD {
|
||||
unsafe { ffi::DTLSv1_method() }
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int {
|
||||
(*s).server
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
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,
|
||||
line!() as c_int,
|
||||
);
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use hash::MessageDigest;
|
|||
use ocsp::{OcspResponse, OcspResponseStatus};
|
||||
use pkey::PKey;
|
||||
use ssl;
|
||||
#[cfg(any(ossl110, ossl111))]
|
||||
#[cfg(any(ossl110, ossl111, libressl261))]
|
||||
use ssl::SslVersion;
|
||||
use ssl::{
|
||||
Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, Ssl, SslAcceptor, SslConnector,
|
||||
|
|
@ -295,8 +295,8 @@ run_test!(verify_callback_data, |method, stream| {
|
|||
match cert {
|
||||
None => false,
|
||||
Some(cert) => {
|
||||
let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
|
||||
fingerprint == node_id
|
||||
let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
|
||||
node_id == &*fingerprint
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -323,8 +323,8 @@ run_test!(ssl_verify_callback, |method, stream| {
|
|||
match x509.current_cert() {
|
||||
None => false,
|
||||
Some(cert) => {
|
||||
let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
|
||||
fingerprint == node_id
|
||||
let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
|
||||
node_id == &*fingerprint
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -424,10 +424,10 @@ run_test!(get_peer_certificate, |method, stream| {
|
|||
let ctx = SslContext::builder(method).unwrap();
|
||||
let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap();
|
||||
let cert = stream.ssl().peer_certificate().unwrap();
|
||||
let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
|
||||
let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
|
||||
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
|
||||
let node_id = Vec::from_hex(node_hash_str).unwrap();
|
||||
assert_eq!(node_id, fingerprint)
|
||||
assert_eq!(node_id, &*fingerprint)
|
||||
});
|
||||
|
||||
#[test]
|
||||
|
|
@ -481,7 +481,7 @@ fn test_state() {
|
|||
/// Tests that connecting with the client using ALPN, but the server not does not
|
||||
/// break the existing connection behavior.
|
||||
#[test]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
fn test_connect_with_unilateral_alpn() {
|
||||
let (_s, stream) = Server::new();
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
|
|
@ -503,7 +503,7 @@ fn test_connect_with_unilateral_alpn() {
|
|||
/// Tests that when both the client as well as the server use ALPN and their
|
||||
/// lists of supported protocols have an overlap, the correct protocol is chosen.
|
||||
#[test]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
fn test_connect_with_alpn_successful_multiple_matching() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
|
|
@ -526,7 +526,7 @@ fn test_connect_with_alpn_successful_multiple_matching() {
|
|||
/// lists of supported protocols have an overlap -- with only ONE protocol
|
||||
/// being valid for both.
|
||||
#[test]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
fn test_connect_with_alpn_successful_single_match() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
|
|
@ -548,7 +548,7 @@ fn test_connect_with_alpn_successful_single_match() {
|
|||
/// Tests that when the `SslStream` is created as a server stream, the protocols
|
||||
/// are correctly advertised to the client.
|
||||
#[test]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
fn test_alpn_server_advertise_multiple() {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let localhost = listener.local_addr().unwrap();
|
||||
|
|
@ -624,7 +624,7 @@ fn test_alpn_server_select_none_fatal() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
fn test_alpn_server_select_none() {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let localhost = listener.local_addr().unwrap();
|
||||
|
|
@ -1063,7 +1063,7 @@ fn tmp_dh_callback() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(all(ossl101, not(libressl)), ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
fn tmp_ecdh_callback() {
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
|
|
@ -1137,7 +1137,7 @@ fn tmp_dh_callback_ssl() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(all(ossl101, not(libressl)), ossl102))]
|
||||
#[cfg(all(ossl101, not(ossl110)))]
|
||||
fn tmp_ecdh_callback_ssl() {
|
||||
use ec::EcKey;
|
||||
use nid::Nid;
|
||||
|
|
@ -1315,7 +1315,7 @@ fn keying_export() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(ossl110))]
|
||||
#[cfg(any(ossl110, libressl261))]
|
||||
fn no_version_overlap() {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
|
@ -1330,7 +1330,7 @@ fn no_version_overlap() {
|
|||
ctx.set_max_proto_version(Some(SslVersion::TLS1_1)).unwrap();
|
||||
#[cfg(ossl110g)]
|
||||
assert_eq!(ctx.min_proto_version(), None);
|
||||
#[cfg(ossl110g)]
|
||||
#[cfg(any(ossl110g, libressl270))]
|
||||
assert_eq!(ctx.max_proto_version(), Some(SslVersion::TLS1_1));
|
||||
let ssl = Ssl::new(&ctx.build()).unwrap();
|
||||
ssl.accept(stream).unwrap_err();
|
||||
|
|
@ -1339,7 +1339,7 @@ fn no_version_overlap() {
|
|||
let stream = TcpStream::connect(addr).unwrap();
|
||||
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
|
||||
ctx.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap();
|
||||
#[cfg(ossl110g)]
|
||||
#[cfg(any(ossl110g, libressl270))]
|
||||
assert_eq!(ctx.min_proto_version(), Some(SslVersion::TLS1_2));
|
||||
#[cfg(ossl110g)]
|
||||
assert_eq!(ctx.max_proto_version(), None);
|
||||
|
|
|
|||
|
|
@ -1,23 +1,30 @@
|
|||
use foreign_types::{ForeignTypeRef, ForeignType, Opaque};
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
|
||||
use libc::c_int;
|
||||
use std::borrow::Borrow;
|
||||
use std::convert::AsRef;
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use ffi;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||
use {cvt, cvt_p};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
|
||||
OPENSSL_sk_new_null, OPENSSL_sk_push,
|
||||
};
|
||||
} else {
|
||||
use ffi::{
|
||||
sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
|
||||
sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK,
|
||||
sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push};
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
|
||||
OPENSSL_sk_new_null, OPENSSL_sk_push};
|
||||
sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait implemented by types which can be placed in a stack.
|
||||
///
|
||||
|
|
@ -33,15 +40,8 @@ pub trait Stackable: ForeignType {
|
|||
/// An owned stack of `T`.
|
||||
pub struct Stack<T: Stackable>(*mut T::StackType);
|
||||
|
||||
impl<T: Stackable> Stack<T> {
|
||||
pub fn new() -> Result<Stack<T>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let ptr = cvt_p(OPENSSL_sk_new_null())?;
|
||||
Ok(Stack(ptr as *mut _))
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe impl<T: Stackable + Send> Send for Stack<T> {}
|
||||
unsafe impl<T: Stackable + Sync> Sync for Stack<T> {}
|
||||
|
||||
impl<T: Stackable> Drop for Stack<T> {
|
||||
fn drop(&mut self) {
|
||||
|
|
@ -52,6 +52,16 @@ impl<T: Stackable> Drop for Stack<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Stackable> Stack<T> {
|
||||
pub fn new() -> Result<Stack<T>, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let ptr = cvt_p(OPENSSL_sk_new_null())?;
|
||||
Ok(Stack(ptr as *mut _))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Stackable> iter::IntoIterator for Stack<T> {
|
||||
type IntoIter = IntoIter<T>;
|
||||
type Item = T;
|
||||
|
|
@ -157,6 +167,9 @@ impl<T: Stackable> ExactSizeIterator for IntoIter<T> {}
|
|||
|
||||
pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
|
||||
|
||||
unsafe impl<T: Stackable + Send> Send for StackRef<T> {}
|
||||
unsafe impl<T: Stackable + Sync> Sync for StackRef<T> {}
|
||||
|
||||
impl<T: Stackable> ForeignTypeRef for StackRef<T> {
|
||||
type CType = T::StackType;
|
||||
}
|
||||
|
|
@ -218,9 +231,7 @@ impl<T: Stackable> StackRef<T> {
|
|||
/// Pushes a value onto the top of the stack.
|
||||
pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(
|
||||
OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _),
|
||||
)?;
|
||||
cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?;
|
||||
mem::forget(data);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@
|
|||
//! println!("Decrypted: '{}'", output_string);
|
||||
//! ```
|
||||
|
||||
use ffi;
|
||||
use libc::c_int;
|
||||
use std::cmp;
|
||||
use std::ptr;
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Mode {
|
||||
|
|
@ -718,34 +718,31 @@ pub fn decrypt_aead(
|
|||
Ok(out)
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use libc::c_int;
|
||||
use ffi::EVP_CIPHER;
|
||||
|
||||
pub unsafe fn EVP_CIPHER_iv_length(ptr: *const EVP_CIPHER) -> c_int {
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length};
|
||||
} else {
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
|
||||
(*ptr).iv_len
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_CIPHER_block_size(ptr: *const EVP_CIPHER) -> c_int {
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int {
|
||||
(*ptr).block_size
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_CIPHER_key_length(ptr: *const EVP_CIPHER) -> c_int {
|
||||
#[allow(bad_style)]
|
||||
pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int {
|
||||
(*ptr).key_len
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(ossl10x)]
|
||||
use self::compat::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use hex::{self, FromHex};
|
||||
use super::*;
|
||||
use hex::{self, FromHex};
|
||||
|
||||
// Test vectors from FIPS-197:
|
||||
// http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||
|
|
|
|||
|
|
@ -13,15 +13,21 @@
|
|||
|
||||
use std::ffi::CStr;
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS,
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
|
||||
OpenSSL_version_num, OpenSSL_version,
|
||||
};
|
||||
} else {
|
||||
use ffi::{
|
||||
SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS,
|
||||
SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM,
|
||||
SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num,
|
||||
SSLeay_version as OpenSSL_version};
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
|
||||
OpenSSL_version_num, OpenSSL_version};
|
||||
SSLeay_version as OpenSSL_version,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// OPENSSL_VERSION_NUMBER is a numeric release version identifier:
|
||||
///
|
||||
|
|
@ -51,7 +57,6 @@ pub fn number() -> i64 {
|
|||
unsafe { OpenSSL_version_num() as 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 {
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
|
||||
//! the secure protocol for browsing the web.
|
||||
|
||||
use libc::{c_int, c_long};
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_int, c_long};
|
||||
use std::error::Error;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fmt;
|
||||
|
|
@ -20,27 +20,20 @@ use std::ptr;
|
|||
use std::slice;
|
||||
use std::str;
|
||||
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef};
|
||||
use bio::MemBioSlice;
|
||||
use conf::ConfRef;
|
||||
use error::ErrorStack;
|
||||
use ex_data::Index;
|
||||
use hash::MessageDigest;
|
||||
use hash::{DigestBytes, MessageDigest};
|
||||
use nid::Nid;
|
||||
use pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
|
||||
use ssl::SslRef;
|
||||
use stack::{Stack, StackRef, Stackable};
|
||||
use string::OpensslString;
|
||||
use ssl::SslRef;
|
||||
use {cvt, cvt_n, cvt_p};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{ASN1_STRING_data, X509_STORE_CTX_get_chain, X509_set_notAfter, X509_set_notBefore};
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{ASN1_STRING_get0_data as ASN1_STRING_data,
|
||||
X509_STORE_CTX_get0_chain as X509_STORE_CTX_get_chain,
|
||||
X509_set1_notAfter as X509_set_notAfter, X509_set1_notBefore as X509_set_notBefore};
|
||||
|
||||
#[cfg(any(ossl102, ossl110))]
|
||||
#[cfg(any(ossl102, libressl261))]
|
||||
pub mod verify;
|
||||
|
||||
pub mod extension;
|
||||
|
|
@ -215,7 +208,7 @@ impl X509StoreContextRef {
|
|||
/// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html
|
||||
pub fn chain(&self) -> Option<&StackRef<X509>> {
|
||||
unsafe {
|
||||
let chain = X509_STORE_CTX_get_chain(self.as_ptr());
|
||||
let chain = X509_STORE_CTX_get0_chain(self.as_ptr());
|
||||
|
||||
if chain.is_null() {
|
||||
None
|
||||
|
|
@ -240,12 +233,12 @@ impl X509Builder {
|
|||
|
||||
/// Sets the notAfter constraint on the certificate.
|
||||
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
|
||||
unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Sets the notBefore constraint on the certificate.
|
||||
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
||||
unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
|
||||
unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Sets the version of the certificate.
|
||||
|
|
@ -454,27 +447,39 @@ impl X509Ref {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns certificate fingerprint calculated using provided hash
|
||||
pub fn fingerprint(&self, hash_type: MessageDigest) -> Result<Vec<u8>, ErrorStack> {
|
||||
/// Returns a digest of the DER representation of the certificate.
|
||||
///
|
||||
/// This corresponds to [`X509_digest`].
|
||||
///
|
||||
/// [`X509_digest`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_digest.html
|
||||
pub fn digest(&self, hash_type: MessageDigest) -> Result<DigestBytes, ErrorStack> {
|
||||
unsafe {
|
||||
let evp = hash_type.as_ptr();
|
||||
let mut digest = DigestBytes {
|
||||
buf: [0; ffi::EVP_MAX_MD_SIZE as usize],
|
||||
len: ffi::EVP_MAX_MD_SIZE as usize,
|
||||
};
|
||||
let mut len = ffi::EVP_MAX_MD_SIZE;
|
||||
let mut buf = vec![0u8; len as usize];
|
||||
cvt(ffi::X509_digest(
|
||||
self.as_ptr(),
|
||||
evp,
|
||||
buf.as_mut_ptr() as *mut _,
|
||||
hash_type.as_ptr(),
|
||||
digest.buf.as_mut_ptr() as *mut _,
|
||||
&mut len,
|
||||
))?;
|
||||
buf.truncate(len as usize);
|
||||
Ok(buf)
|
||||
digest.len = len as usize;
|
||||
|
||||
Ok(digest)
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.10.9", note = "renamed to digest")]
|
||||
pub fn fingerprint(&self, hash_type: MessageDigest) -> Result<Vec<u8>, ErrorStack> {
|
||||
self.digest(hash_type).map(|b| b.to_vec())
|
||||
}
|
||||
|
||||
/// Returns the certificate's Not After validity period.
|
||||
pub fn not_after(&self) -> &Asn1TimeRef {
|
||||
unsafe {
|
||||
let date = compat::X509_get_notAfter(self.as_ptr());
|
||||
let date = X509_getm_notAfter(self.as_ptr());
|
||||
assert!(!date.is_null());
|
||||
Asn1TimeRef::from_ptr(date)
|
||||
}
|
||||
|
|
@ -483,7 +488,7 @@ impl X509Ref {
|
|||
/// Returns the certificate's Not Before validity period.
|
||||
pub fn not_before(&self) -> &Asn1TimeRef {
|
||||
unsafe {
|
||||
let date = compat::X509_get_notBefore(self.as_ptr());
|
||||
let date = X509_getm_notBefore(self.as_ptr());
|
||||
assert!(!date.is_null());
|
||||
Asn1TimeRef::from_ptr(date)
|
||||
}
|
||||
|
|
@ -493,7 +498,7 @@ impl X509Ref {
|
|||
pub fn signature(&self) -> &Asn1BitStringRef {
|
||||
unsafe {
|
||||
let mut signature = ptr::null();
|
||||
compat::X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr());
|
||||
X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr());
|
||||
assert!(!signature.is_null());
|
||||
Asn1BitStringRef::from_ptr(signature as *mut _)
|
||||
}
|
||||
|
|
@ -503,7 +508,7 @@ impl X509Ref {
|
|||
pub fn signature_algorithm(&self) -> &X509AlgorithmRef {
|
||||
unsafe {
|
||||
let mut algor = ptr::null();
|
||||
compat::X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
|
||||
X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
|
||||
assert!(!algor.is_null());
|
||||
X509AlgorithmRef::from_ptr(algor as *mut _)
|
||||
}
|
||||
|
|
@ -564,7 +569,7 @@ impl ToOwned for X509Ref {
|
|||
|
||||
fn to_owned(&self) -> X509 {
|
||||
unsafe {
|
||||
compat::X509_up_ref(self.as_ptr());
|
||||
X509_up_ref(self.as_ptr());
|
||||
X509::from_ptr(self.as_ptr())
|
||||
}
|
||||
}
|
||||
|
|
@ -1054,7 +1059,7 @@ impl X509ReqRef {
|
|||
///
|
||||
/// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html
|
||||
pub fn version(&self) -> i32 {
|
||||
unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 }
|
||||
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
|
||||
}
|
||||
|
||||
/// Returns the subject name of the certificate request.
|
||||
|
|
@ -1064,7 +1069,7 @@ impl X509ReqRef {
|
|||
/// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html
|
||||
pub fn subject_name(&self) -> &X509NameRef {
|
||||
unsafe {
|
||||
let name = compat::X509_REQ_get_subject_name(self.as_ptr());
|
||||
let name = X509_REQ_get_subject_name(self.as_ptr());
|
||||
assert!(!name.is_null());
|
||||
X509NameRef::from_ptr(name)
|
||||
}
|
||||
|
|
@ -1172,7 +1177,7 @@ impl GeneralNameRef {
|
|||
return None;
|
||||
}
|
||||
|
||||
let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
|
||||
let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
|
||||
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
|
||||
|
||||
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
|
||||
|
|
@ -1205,7 +1210,7 @@ impl GeneralNameRef {
|
|||
return None;
|
||||
}
|
||||
|
||||
let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
|
||||
let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _);
|
||||
let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
|
||||
|
||||
Some(slice::from_raw_parts(ptr as *const u8, len as usize))
|
||||
|
|
@ -1232,39 +1237,41 @@ impl X509AlgorithmRef {
|
|||
pub fn object(&self) -> &Asn1ObjectRef {
|
||||
unsafe {
|
||||
let mut oid = ptr::null();
|
||||
compat::X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
|
||||
X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
|
||||
assert!(!oid.is_null());
|
||||
Asn1ObjectRef::from_ptr(oid as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
mod compat {
|
||||
pub use ffi::X509_getm_notAfter as X509_get_notAfter;
|
||||
pub use ffi::X509_getm_notBefore as X509_get_notBefore;
|
||||
pub use ffi::X509_up_ref;
|
||||
pub use ffi::X509_REQ_get_version;
|
||||
pub use ffi::X509_REQ_get_subject_name;
|
||||
pub use ffi::X509_get0_signature;
|
||||
pub use ffi::X509_ALGOR_get0;
|
||||
}
|
||||
cfg_if! {
|
||||
if #[cfg(ossl110)] {
|
||||
use ffi::{
|
||||
X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version,
|
||||
X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref,
|
||||
ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter,
|
||||
X509_set1_notBefore,
|
||||
};
|
||||
} else {
|
||||
use ffi::{
|
||||
ASN1_STRING_data as ASN1_STRING_get0_data,
|
||||
X509_STORE_CTX_get_chain as X509_STORE_CTX_get0_chain,
|
||||
X509_set_notAfter as X509_set1_notAfter,
|
||||
X509_set_notBefore as X509_set1_notBefore,
|
||||
};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
#[allow(bad_style)]
|
||||
mod compat {
|
||||
use libc::{c_int, c_void};
|
||||
use ffi;
|
||||
|
||||
pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn X509_getm_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
|
||||
(*(*(*x).cert_info).validity).notAfter
|
||||
}
|
||||
|
||||
pub unsafe fn X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn X509_getm_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
|
||||
(*(*(*x).cert_info).validity).notBefore
|
||||
}
|
||||
|
||||
pub unsafe fn X509_up_ref(x: *mut ffi::X509) {
|
||||
#[allow(bad_style)]
|
||||
unsafe fn X509_up_ref(x: *mut ffi::X509) {
|
||||
ffi::CRYPTO_add_lock(
|
||||
&mut (*x).references,
|
||||
1,
|
||||
|
|
@ -1274,15 +1281,18 @@ mod compat {
|
|||
);
|
||||
}
|
||||
|
||||
pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
|
||||
::ffi::ASN1_INTEGER_get((*(*x).req_info).version)
|
||||
#[allow(bad_style)]
|
||||
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 {
|
||||
#[allow(bad_style)]
|
||||
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(
|
||||
#[allow(bad_style)]
|
||||
unsafe fn X509_get0_signature(
|
||||
psig: *mut *const ffi::ASN1_BIT_STRING,
|
||||
palg: *mut *const ffi::X509_ALGOR,
|
||||
x: *const ffi::X509,
|
||||
|
|
@ -1295,10 +1305,11 @@ mod compat {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn X509_ALGOR_get0(
|
||||
#[allow(bad_style)]
|
||||
unsafe fn X509_ALGOR_get0(
|
||||
paobj: *mut *const ffi::ASN1_OBJECT,
|
||||
pptype: *mut c_int,
|
||||
pval: *mut *mut c_void,
|
||||
pval: *mut *mut ::libc::c_void,
|
||||
alg: *const ffi::X509_ALGOR,
|
||||
) {
|
||||
if !paobj.is_null() {
|
||||
|
|
@ -1307,4 +1318,5 @@ mod compat {
|
|||
assert!(pptype.is_null());
|
||||
assert!(pval.is_null());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ use ffi;
|
|||
use foreign_types::ForeignTypeRef;
|
||||
use std::mem;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use x509::X509;
|
||||
use {cvt, cvt_p};
|
||||
|
||||
foreign_type! {
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
|
|
@ -82,9 +82,7 @@ impl X509StoreBuilderRef {
|
|||
/// Adds a certificate to the certificate store.
|
||||
// FIXME should take an &X509Ref
|
||||
pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ())
|
||||
}
|
||||
unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
|
||||
}
|
||||
|
||||
/// Load certificates from their default locations.
|
||||
|
|
@ -97,7 +95,7 @@ impl X509StoreBuilderRef {
|
|||
}
|
||||
}
|
||||
|
||||
foreign_type! {
|
||||
foreign_type_and_impl_send_sync! {
|
||||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ use nid::Nid;
|
|||
use pkey::{PKey, Private};
|
||||
use rsa::Rsa;
|
||||
use stack::Stack;
|
||||
use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
|
||||
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
|
||||
SubjectAlternativeName, SubjectKeyIdentifier};
|
||||
use x509::extension::{
|
||||
AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
|
||||
SubjectKeyIdentifier,
|
||||
};
|
||||
use x509::store::X509StoreBuilder;
|
||||
use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult};
|
||||
|
||||
fn pkey() -> PKey<Private> {
|
||||
let rsa = Rsa::generate(2048).unwrap();
|
||||
|
|
@ -21,12 +23,12 @@ fn pkey() -> PKey<Private> {
|
|||
fn test_cert_loading() {
|
||||
let cert = include_bytes!("../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
|
||||
let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
|
||||
|
||||
let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
|
||||
let hash_vec = Vec::from_hex(hash_str).unwrap();
|
||||
|
||||
assert_eq!(fingerprint, hash_vec);
|
||||
assert_eq!(hash_vec, &*fingerprint);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -197,7 +199,8 @@ fn x509_builder() {
|
|||
|
||||
assert!(pkey.public_eq(&x509.public_key().unwrap()));
|
||||
|
||||
let cn = x509.subject_name()
|
||||
let cn = x509
|
||||
.subject_name()
|
||||
.entries_by_nid(Nid::COMMONNAME)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
|
@ -247,11 +250,11 @@ fn test_stack_from_pem() {
|
|||
|
||||
assert_eq!(certs.len(), 2);
|
||||
assert_eq!(
|
||||
hex::encode(certs[0].fingerprint(MessageDigest::sha1()).unwrap()),
|
||||
hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()),
|
||||
"59172d9313e84459bcff27f967e79e6e9217e584"
|
||||
);
|
||||
assert_eq!(
|
||||
hex::encode(certs[1].fingerprint(MessageDigest::sha1()).unwrap()),
|
||||
hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()),
|
||||
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
|
||||
);
|
||||
}
|
||||
|
|
@ -291,7 +294,7 @@ fn signature() {
|
|||
fn clone_x509() {
|
||||
let cert = include_bytes!("../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).unwrap();
|
||||
cert.clone();
|
||||
drop(cert.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use libc::c_uint;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::c_uint;
|
||||
use std::net::IpAddr;
|
||||
|
||||
use cvt;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ extern crate ctest;
|
|||
|
||||
use std::env;
|
||||
|
||||
#[path = "../openssl-sys/build/cfgs.rs"]
|
||||
mod cfgs;
|
||||
|
||||
fn main() {
|
||||
let mut cfg = ctest::TestGenerator::new();
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let mut is_libressl = false;
|
||||
|
||||
if let Ok(out) = env::var("DEP_OPENSSL_INCLUDE") {
|
||||
cfg.include(&out);
|
||||
|
|
@ -26,21 +28,17 @@ fn main() {
|
|||
cfg.define("WIN32_LEAN_AND_MEAN", None);
|
||||
}
|
||||
|
||||
if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") {
|
||||
cfg.cfg("libressl", None);
|
||||
is_libressl = true;
|
||||
} else if let Ok(version) = env::var("DEP_OPENSSL_VERSION") {
|
||||
cfg.cfg(&format!("ossl{}", version), None);
|
||||
if version == "111" {
|
||||
cfg.cfg("ossl110", None);
|
||||
}
|
||||
}
|
||||
if let (Ok(version), Ok(patch)) = (
|
||||
env::var("DEP_OPENSSL_VERSION"),
|
||||
env::var("DEP_OPENSSL_PATCH"),
|
||||
) {
|
||||
cfg.cfg(&format!("ossl{}{}", version, patch), None);
|
||||
let openssl_version = env::var("DEP_OPENSSL_VERSION_NUMBER")
|
||||
.ok()
|
||||
.map(|v| u64::from_str_radix(&v, 16).unwrap());
|
||||
let libressl_version = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER")
|
||||
.ok()
|
||||
.map(|v| u64::from_str_radix(&v, 16).unwrap());
|
||||
|
||||
for c in cfgs::get(openssl_version, libressl_version) {
|
||||
cfg.cfg(c, None);
|
||||
}
|
||||
|
||||
if let Ok(vars) = env::var("DEP_OPENSSL_CONF") {
|
||||
for var in vars.split(",") {
|
||||
cfg.cfg("osslconf", Some(var));
|
||||
|
|
@ -65,7 +63,7 @@ fn main() {
|
|||
.header("openssl/ocsp.h")
|
||||
.header("openssl/evp.h");
|
||||
|
||||
if !is_libressl {
|
||||
if openssl_version.is_some() {
|
||||
cfg.header("openssl/cms.h");
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +77,8 @@ 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"
|
||||
} else if is_struct
|
||||
&& s != "point_conversion_form_t"
|
||||
&& s.chars().next().unwrap().is_lowercase()
|
||||
{
|
||||
format!("struct {}", s)
|
||||
|
|
@ -111,9 +110,13 @@ fn main() {
|
|||
(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_func") || s.ends_with("_cb_ex")
|
||||
s.ends_with("_cb")
|
||||
|| s.ends_with("_CB")
|
||||
|| s.ends_with("_cb_fn")
|
||||
|| s.starts_with("CRYPTO_")
|
||||
|| s == "PasswordCallback"
|
||||
|| s.ends_with("_cb_func")
|
||||
|| s.ends_with("_cb_ex")
|
||||
});
|
||||
cfg.field_name(|_s, field| {
|
||||
if field == "type_" {
|
||||
|
|
|
|||
Loading…
Reference in New Issue