Merge branch 'master' into x509_req_version_subject
This commit is contained in:
commit
30a634c877
12
.travis.yml
12
.travis.yml
|
|
@ -19,7 +19,7 @@ matrix:
|
|||
# ARM-bit version compat
|
||||
- env: >
|
||||
TARGET=arm-unknown-linux-gnueabihf
|
||||
BUILD_OPENSSL_VERSION=1.0.2h
|
||||
BUILD_OPENSSL_VERSION=1.0.2k
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
|
||||
QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf
|
||||
RUST_TEST_THREADS=1
|
||||
|
|
@ -32,7 +32,7 @@ matrix:
|
|||
- binfmt-support
|
||||
- env: >
|
||||
TARGET=arm-unknown-linux-gnueabihf
|
||||
BUILD_OPENSSL_VERSION=1.1.0c
|
||||
BUILD_OPENSSL_VERSION=1.1.0d
|
||||
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc
|
||||
QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf
|
||||
RUST_TEST_THREADS=1
|
||||
|
|
@ -52,8 +52,8 @@ matrix:
|
|||
- rust: nightly
|
||||
|
||||
# 64-bit version compat
|
||||
- env: BUILD_OPENSSL_VERSION=1.0.2h
|
||||
- env: BUILD_OPENSSL_VERSION=1.1.0c
|
||||
- env: BUILD_OPENSSL_VERSION=1.0.2k
|
||||
- env: BUILD_OPENSSL_VERSION=1.1.0d
|
||||
|
||||
# 32-bit version compat
|
||||
- env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.1u
|
||||
|
|
@ -61,12 +61,12 @@ matrix:
|
|||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2h
|
||||
- env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.0.2k
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0c
|
||||
- env: TARGET=i686-unknown-linux-gnu BUILD_OPENSSL_VERSION=1.1.0d
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ environment:
|
|||
- TARGET: i686-pc-windows-gnu
|
||||
BITS: 32
|
||||
MSYS2: 1
|
||||
OPENSSL_VERSION: 1_1_0c
|
||||
OPENSSL_VERSION: 1_1_0d
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
BITS: 64
|
||||
OPENSSL_VERSION: 1_1_0c
|
||||
OPENSSL_VERSION: 1_1_0d
|
||||
OPENSSL_DIR: C:\OpenSSL
|
||||
|
||||
# 1.0.2, 64/32 bit
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
BITS: 64
|
||||
MSYS2: 1
|
||||
OPENSSL_VERSION: 1_0_2j
|
||||
OPENSSL_VERSION: 1_0_2k
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
BITS: 32
|
||||
OPENSSL_VERSION: 1_0_2j
|
||||
OPENSSL_VERSION: 1_0_2k
|
||||
OPENSSL_DIR: C:\OpenSSL
|
||||
install:
|
||||
# install OpenSSL
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@ libc = "0.2"
|
|||
|
||||
[build-dependencies]
|
||||
pkg-config = "0.3.9"
|
||||
gcc = "0.3.42"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
user32-sys = "0.2"
|
||||
gdi32-sys = "0.2"
|
||||
|
||||
# We don't actually use metadeps for annoying reasons but this is still hear for tooling
|
||||
# We don't actually use metadeps for annoying reasons but this is still here for tooling
|
||||
[package.metadata.pkg-config]
|
||||
openssl = "1.0.1"
|
||||
|
|
|
|||
|
|
@ -1,13 +1,38 @@
|
|||
extern crate pkg_config;
|
||||
extern crate gcc;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::panic::{self, AssertUnwindSafe};
|
||||
use std::process::Command;
|
||||
|
||||
// The set of `OPENSSL_NO_<FOO>`s that we care about.
|
||||
const DEFINES: &'static [&'static str] = &[
|
||||
"OPENSSL_NO_BUF_FREELISTS",
|
||||
"OPENSSL_NO_COMP",
|
||||
"OPENSSL_NO_EC",
|
||||
"OPENSSL_NO_ENGINE",
|
||||
"OPENSSL_NO_KRB5",
|
||||
"OPENSSL_NO_NEXTPROTONEG",
|
||||
"OPENSSL_NO_PSK",
|
||||
"OPENSSL_NO_RFC3779",
|
||||
"OPENSSL_NO_SHA",
|
||||
"OPENSSL_NO_SRP",
|
||||
"OPENSSL_NO_SSL3_METHOD",
|
||||
"OPENSSL_NO_TLSEXT",
|
||||
];
|
||||
|
||||
enum Version {
|
||||
Openssl110,
|
||||
Openssl102,
|
||||
Openssl101,
|
||||
Libressl,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
|
||||
|
|
@ -38,17 +63,14 @@ fn main() {
|
|||
println!("cargo:rustc-link-search=native={}", lib_dir.to_string_lossy());
|
||||
println!("cargo:include={}", include_dir.to_string_lossy());
|
||||
|
||||
let version = validate_headers(&[include_dir.clone().into()],
|
||||
&[lib_dir.clone().into()]);
|
||||
let version = validate_headers(&[include_dir.clone().into()]);
|
||||
|
||||
let libs = if (version.contains("0x10001") ||
|
||||
version.contains("0x10002")) &&
|
||||
target.contains("windows") {
|
||||
["ssleay32", "libeay32"]
|
||||
} else if target.contains("windows") {
|
||||
["libssl", "libcrypto"]
|
||||
} else {
|
||||
["ssl", "crypto"]
|
||||
let libs = match version {
|
||||
Version::Openssl101 | Version::Openssl102 if target.contains("windows") => {
|
||||
["ssleay32", "libeay32"]
|
||||
}
|
||||
Version::Openssl110 if target.contains("windows") => ["libssl", "libcrypto"],
|
||||
_ => ["ssl", "crypto"],
|
||||
};
|
||||
|
||||
let kind = determine_mode(Path::new(&lib_dir), &libs);
|
||||
|
|
@ -168,29 +190,79 @@ fn try_pkg_config() {
|
|||
return
|
||||
}
|
||||
|
||||
// We're going to be looking at header files, so show us all the system
|
||||
// cflags dirs for showing us lots of `-I`.
|
||||
env::set_var("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", "1");
|
||||
let lib = pkg_config::Config::new()
|
||||
.print_system_libs(false)
|
||||
.find("openssl")
|
||||
.unwrap();
|
||||
|
||||
// This is more complex than normal because we need to track down opensslconf.h.
|
||||
// To do that, we need the inlude paths even if they're on the default search path, but the
|
||||
// linkage directories emitted from that cause all kinds of issues if other libraries happen to
|
||||
// live in them. So, we run pkg-config twice, once asking for system dirs but not emitting
|
||||
// metadata, and a second time emitting metadata but not asking for system dirs. Yay.
|
||||
let lib = match pkg_config::Config::new()
|
||||
.cargo_metadata(false)
|
||||
.print_system_libs(true)
|
||||
.find("openssl") {
|
||||
Ok(lib) => lib,
|
||||
Err(_) => return,
|
||||
};
|
||||
validate_headers(&lib.include_paths);
|
||||
|
||||
if lib.include_paths.len() == 0 {
|
||||
panic!("
|
||||
for include in lib.include_paths.iter() {
|
||||
println!("cargo:include={}", include.display());
|
||||
}
|
||||
|
||||
Used pkg-config to discover the OpenSSL installation, but pkg-config did not
|
||||
return any include paths for the installation. This crate needs to take a peek
|
||||
at the header files so it cannot proceed unless they're found.
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
/// Validates the header files found in `include_dir` and then returns the
|
||||
/// version string of OpenSSL.
|
||||
fn validate_headers(include_dirs: &[PathBuf]) -> Version {
|
||||
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
|
||||
// correctly expose the right API from this crate, take a look at
|
||||
// `opensslv.h` to see what version OpenSSL claims to be.
|
||||
//
|
||||
// OpenSSL has a number of build-time configuration options which affect
|
||||
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
|
||||
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
|
||||
//
|
||||
// To handle all this conditional compilation we slurp up the configuration
|
||||
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
|
||||
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
|
||||
// account for compile differences and such.
|
||||
let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
path.push("expando.c");
|
||||
let mut file = BufWriter::new(File::create(&path).unwrap());
|
||||
|
||||
write!(file, "\
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef LIBRESSL_VERSION_NUMBER
|
||||
RUST_LIBRESSL
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10200000
|
||||
RUST_OPENSSL_NEW
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10100000
|
||||
RUST_OPENSSL_110
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10002000
|
||||
RUST_OPENSSL_102
|
||||
#elif OPENSSL_VERSION_NUMBER >= 0x10001000
|
||||
RUST_OPENSSL_101
|
||||
#else
|
||||
RUST_OPENSSL_OLD
|
||||
#endif
|
||||
").unwrap();
|
||||
|
||||
for define in DEFINES {
|
||||
write!(file, "\
|
||||
#ifdef {define}
|
||||
RUST_{define}
|
||||
#endif
|
||||
", define = define).unwrap();
|
||||
}
|
||||
|
||||
file.flush().unwrap();
|
||||
drop(file);
|
||||
|
||||
let mut gcc = gcc::Config::new();
|
||||
for include_dir in include_dirs {
|
||||
gcc.include(include_dir);
|
||||
}
|
||||
// https://github.com/alexcrichton/gcc-rs/issues/133
|
||||
let expanded = match panic::catch_unwind(AssertUnwindSafe(|| gcc.file(&path).expand())) {
|
||||
Ok(expanded) => expanded,
|
||||
Err(_) => {
|
||||
panic!("
|
||||
Failed to find OpenSSL development headers.
|
||||
|
||||
You can try fixing this setting the `OPENSSL_DIR` environment variable
|
||||
pointing to your OpenSSL installation or installing OpenSSL headers package
|
||||
|
|
@ -207,150 +279,45 @@ See rust-openssl README for more information:
|
|||
|
||||
https://github.com/sfackler/rust-openssl#linux
|
||||
");
|
||||
}
|
||||
|
||||
validate_headers(&lib.include_paths, &lib.link_paths);
|
||||
|
||||
for include in lib.include_paths.iter() {
|
||||
println!("cargo:include={}", include.display());
|
||||
}
|
||||
|
||||
pkg_config::Config::new()
|
||||
.print_system_libs(false)
|
||||
.find("openssl")
|
||||
.unwrap();
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
/// Validates the header files found in `include_dir` and then returns the
|
||||
/// version string of OpenSSL.
|
||||
fn validate_headers(include_dirs: &[PathBuf],
|
||||
libdirs: &[PathBuf]) -> String {
|
||||
// This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, and 1.1.0. To
|
||||
// correctly expose the right API from this crate, take a look at
|
||||
// `opensslv.h` to see what version OpenSSL claims to be.
|
||||
let mut version_header = String::new();
|
||||
let mut include = include_dirs.iter()
|
||||
.map(|p| p.join("openssl/opensslv.h"))
|
||||
.filter(|p| p.exists());
|
||||
let mut f = match include.next() {
|
||||
Some(f) => File::open(f).unwrap(),
|
||||
None => {
|
||||
panic!("failed to open header file at `openssl/opensslv.h` to learn
|
||||
about OpenSSL's version number, looked inside:\n\n{:#?}\n\n",
|
||||
include_dirs);
|
||||
}
|
||||
};
|
||||
f.read_to_string(&mut version_header).unwrap();
|
||||
let expanded = String::from_utf8(expanded).unwrap();
|
||||
|
||||
// Do a bit of string parsing to find `#define OPENSSL_VERSION_NUMBER ...`
|
||||
let version_line = version_header.lines().find(|l| {
|
||||
l.contains("define ") && l.contains("OPENSSL_VERSION_NUMBER")
|
||||
}).and_then(|line| {
|
||||
let start = match line.find("0x") {
|
||||
Some(start) => start,
|
||||
None => return None,
|
||||
};
|
||||
Some(line[start..].trim())
|
||||
});
|
||||
let version_text = match version_line {
|
||||
Some(text) => text,
|
||||
None => {
|
||||
panic!("header file at `{}` did not include `OPENSSL_VERSION_NUMBER` \
|
||||
that this crate recognized, failed to learn about the \
|
||||
OpenSSL version number");
|
||||
let mut enabled = vec![];
|
||||
for &define in DEFINES {
|
||||
if expanded.contains(&format!("RUST_{}", define)) {
|
||||
println!("cargo:rustc-cfg=osslconf=\"{}\"", define);
|
||||
enabled.push(define);
|
||||
}
|
||||
};
|
||||
if version_text.contains("0x10001") {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
}
|
||||
println!("cargo:conf={}", enabled.join(","));
|
||||
|
||||
if expanded.contains("RUST_LIBRESSL") {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:version=101");
|
||||
} else if version_text.contains("0x10002") {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:version=102");
|
||||
} else if version_text.contains("0x10100") {
|
||||
Version::Libressl
|
||||
} else if expanded.contains("RUST_OPENSSL_110") {
|
||||
println!("cargo:rustc-cfg=ossl110");
|
||||
println!("cargo:version=110");
|
||||
} else if version_text.contains("0x20000000L") {
|
||||
// Check if it is really LibreSSL
|
||||
if version_header.lines().any(|l| {
|
||||
l.contains("define ") && l.contains("LIBRESSL_VERSION_NUMBER")
|
||||
}) {
|
||||
println!("cargo:rustc-cfg=libressl");
|
||||
println!("cargo:libressl=true");
|
||||
println!("cargo:version=101");
|
||||
}
|
||||
Version::Openssl110
|
||||
} else if expanded.contains("RUST_OPENSSL_102") {
|
||||
println!("cargo:rustc-cfg=ossl102");
|
||||
println!("cargo:version=102");
|
||||
Version::Openssl102
|
||||
} else if expanded.contains("RUST_OPENSSL_101") {
|
||||
println!("cargo:rustc-cfg=ossl101");
|
||||
println!("cargo:version=101");
|
||||
Version::Openssl101
|
||||
} else {
|
||||
panic!("
|
||||
|
||||
This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, but a
|
||||
different version of OpenSSL was found:
|
||||
This crate is only compatible with OpenSSL 1.0.1, 1.0.2, and 1.1.0, or LibreSSL,
|
||||
but a different version of OpenSSL was found. The build is now aborting due to
|
||||
this version mismatch.
|
||||
|
||||
{}
|
||||
|
||||
The build is now aborting due to this version mismatch.
|
||||
|
||||
", version_text);
|
||||
");
|
||||
}
|
||||
|
||||
// OpenSSL has a number of build-time configuration options which affect
|
||||
// various structs and such. Since OpenSSL 1.1.0 this isn't really a problem
|
||||
// as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem.
|
||||
//
|
||||
// To handle all this conditional compilation we slurp up the configuration
|
||||
// file of OpenSSL, `opensslconf.h`, and then dump out everything it defines
|
||||
// as our own #[cfg] directives. That way the `ossl10x.rs` bindings can
|
||||
// account for compile differences and such.
|
||||
let mut conf_header = String::new();
|
||||
let mut include = include_dirs.iter()
|
||||
.map(|p| p.join("openssl/opensslconf.h"))
|
||||
.filter(|p| p.exists());
|
||||
let mut f = match include.next() {
|
||||
Some(f) => File::open(f).unwrap(),
|
||||
None => {
|
||||
// It's been seen that on linux the include dir printed out by
|
||||
// `pkg-config` doesn't actually have opensslconf.h. Instead
|
||||
// it's in an architecture-specific include directory.
|
||||
//
|
||||
// Try to detect that case to see if it exists.
|
||||
let mut libdirs = libdirs.iter().map(|p| {
|
||||
p.iter()
|
||||
.map(|p| if p == "lib" {"include".as_ref()} else {p})
|
||||
.collect::<PathBuf>()
|
||||
}).map(|p| {
|
||||
p.join("openssl/opensslconf.h")
|
||||
}).filter(|p| p.exists());
|
||||
match libdirs.next() {
|
||||
Some(f) => File::open(f).unwrap(),
|
||||
None => {
|
||||
panic!("failed to open header file at
|
||||
`openssl/opensslconf.h` to learn about \
|
||||
OpenSSL's version number, looked \
|
||||
inside:\n\n{:#?}\n\n",
|
||||
include_dirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
f.read_to_string(&mut conf_header).unwrap();
|
||||
|
||||
// Look for `#define OPENSSL_FOO`, print out everything as our own
|
||||
// #[cfg] flag.
|
||||
let mut vars = vec![];
|
||||
for line in conf_header.lines() {
|
||||
let i = match line.find("define ") {
|
||||
Some(i) => i,
|
||||
None => continue,
|
||||
};
|
||||
let var = line[i + "define ".len()..].trim();
|
||||
if var.starts_with("OPENSSL") && !var.contains(" ") {
|
||||
println!("cargo:rustc-cfg=osslconf=\"{}\"", var);
|
||||
vars.push(var);
|
||||
}
|
||||
}
|
||||
println!("cargo:conf={}", vars.join(","));
|
||||
|
||||
return version_text.to_string()
|
||||
}
|
||||
|
||||
/// Given a libdir for OpenSSL (where artifacts are located) as well as the name
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ pub const EVP_PKEY_DSA: c_int = NID_dsa;
|
|||
pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement;
|
||||
pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey;
|
||||
|
||||
pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000;
|
||||
|
||||
pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1;
|
||||
|
||||
pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6;
|
||||
|
||||
pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9;
|
||||
pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10;
|
||||
pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11;
|
||||
|
|
@ -1303,6 +1309,15 @@ pub unsafe fn BIO_set_retry_write(b: *mut BIO) {
|
|||
BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY)
|
||||
}
|
||||
|
||||
// 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(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, ptr::null_mut())
|
||||
}
|
||||
|
||||
pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int {
|
||||
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad as *mut c_void)
|
||||
}
|
||||
|
||||
pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long {
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut())
|
||||
}
|
||||
|
|
@ -1632,6 +1647,9 @@ extern {
|
|||
key: *const c_uchar,
|
||||
keylen: c_int) -> *mut EVP_PKEY;
|
||||
|
||||
|
||||
pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int;
|
||||
|
||||
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
|
||||
|
||||
pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ v110 = []
|
|||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
foreign-types = "0.1"
|
||||
lazy_static = "0.2"
|
||||
libc = "0.2"
|
||||
openssl-sys = { version = "0.9.6", path = "../openssl-sys" }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_long, c_char};
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
|
|
@ -8,10 +9,15 @@ use std::str;
|
|||
use {cvt, cvt_p};
|
||||
use bio::MemBio;
|
||||
use error::ErrorStack;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use string::OpensslString;
|
||||
|
||||
type_!(Asn1GeneralizedTime, Asn1GeneralizedTimeRef, ffi::ASN1_GENERALIZEDTIME, ffi::ASN1_GENERALIZEDTIME_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::ASN1_GENERALIZEDTIME;
|
||||
fn drop = ffi::ASN1_GENERALIZEDTIME_free;
|
||||
|
||||
pub struct Asn1GeneralizedTime;
|
||||
pub struct Asn1GeneralizedTimeRef;
|
||||
}
|
||||
|
||||
impl fmt::Display for Asn1GeneralizedTimeRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
|
@ -23,7 +29,13 @@ impl fmt::Display for Asn1GeneralizedTimeRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(Asn1Time, Asn1TimeRef, ffi::ASN1_TIME, ffi::ASN1_TIME_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::ASN1_TIME;
|
||||
fn drop = ffi::ASN1_TIME_free;
|
||||
|
||||
pub struct Asn1Time;
|
||||
pub struct Asn1TimeRef;
|
||||
}
|
||||
|
||||
impl fmt::Display for Asn1TimeRef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
|
@ -51,7 +63,13 @@ impl Asn1Time {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(Asn1String, Asn1StringRef, ffi::ASN1_STRING, ffi::ASN1_STRING_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::ASN1_STRING;
|
||||
fn drop = ffi::ASN1_STRING_free;
|
||||
|
||||
pub struct Asn1String;
|
||||
pub struct Asn1StringRef;
|
||||
}
|
||||
|
||||
impl Asn1StringRef {
|
||||
pub fn as_utf8(&self) -> Result<OpensslString, ErrorStack> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::cmp::Ordering;
|
||||
use std::ffi::CString;
|
||||
|
|
@ -8,7 +9,6 @@ use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
|
|||
use {cvt, cvt_p, cvt_n};
|
||||
use error::ErrorStack;
|
||||
use string::OpensslString;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
use ffi::{get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
|
||||
|
|
@ -40,7 +40,13 @@ pub const MSB_ONE: MsbOption = MsbOption(0);
|
|||
/// of bits in the original numbers.
|
||||
pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
|
||||
|
||||
type_!(BigNumContext, BigNumContextRef, ffi::BN_CTX, ffi::BN_CTX_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::BN_CTX;
|
||||
fn drop = ffi::BN_CTX_free;
|
||||
|
||||
pub struct BigNumContext;
|
||||
pub struct BigNumContextRef;
|
||||
}
|
||||
|
||||
impl BigNumContext {
|
||||
/// Returns a new `BigNumContext`.
|
||||
|
|
@ -509,7 +515,13 @@ impl BigNumRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(BigNum, BigNumRef, ffi::BIGNUM, ffi::BN_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::BIGNUM;
|
||||
fn drop = ffi::BN_free;
|
||||
|
||||
pub struct BigNum;
|
||||
pub struct BigNumRef;
|
||||
}
|
||||
|
||||
impl BigNum {
|
||||
/// Creates a new `BigNum` with the value 0.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p, init};
|
||||
use bn::BigNum;
|
||||
use types::OpenSslTypeRef;
|
||||
|
||||
type_!(Dh, DhRef, ffi::DH, ffi::DH_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::DH;
|
||||
fn drop = ffi::DH_free;
|
||||
|
||||
pub struct Dh;
|
||||
|
||||
pub struct DhRef;
|
||||
}
|
||||
|
||||
impl DhRef {
|
||||
to_pem!(ffi::PEM_write_bio_DHparams);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::{c_int, c_char, c_void};
|
||||
use std::fmt;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBioSlice;
|
||||
use bn::BigNumRef;
|
||||
use {cvt, cvt_p};
|
||||
use types::OpenSslTypeRef;
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb_old};
|
||||
|
||||
type_!(Dsa, DsaRef, ffi::DSA, ffi::DSA_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::DSA;
|
||||
fn drop = ffi::DSA_free;
|
||||
|
||||
pub struct Dsa;
|
||||
pub struct DsaRef;
|
||||
}
|
||||
|
||||
impl DsaRef {
|
||||
private_key_to_pem!(ffi::PEM_write_bio_DSAPrivateKey);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use libc::c_int;
|
||||
|
|
@ -7,7 +8,6 @@ use {cvt, cvt_n, cvt_p, init};
|
|||
use bn::{BigNumRef, BigNumContextRef};
|
||||
use error::ErrorStack;
|
||||
use nid::Nid;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
|
||||
pub const POINT_CONVERSION_COMPRESSED: PointConversionForm =
|
||||
PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED);
|
||||
|
|
@ -29,7 +29,13 @@ pub struct PointConversionForm(ffi::point_conversion_form_t);
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Asn1Flag(c_int);
|
||||
|
||||
type_!(EcGroup, EcGroupRef, ffi::EC_GROUP, ffi::EC_GROUP_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::EC_GROUP;
|
||||
fn drop = ffi::EC_GROUP_free;
|
||||
|
||||
pub struct EcGroup;
|
||||
pub struct EcGroupRef;
|
||||
}
|
||||
|
||||
impl EcGroup {
|
||||
/// Returns the group of a standard named curve.
|
||||
|
|
@ -103,7 +109,13 @@ impl EcGroupRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(EcPoint, EcPointRef, ffi::EC_POINT, ffi::EC_POINT_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::EC_POINT;
|
||||
fn drop = ffi::EC_POINT_free;
|
||||
|
||||
pub struct EcPoint;
|
||||
pub struct EcPointRef;
|
||||
}
|
||||
|
||||
impl EcPointRef {
|
||||
/// Computes `a + b`, storing the result in `self`.
|
||||
|
|
@ -253,7 +265,13 @@ impl EcPoint {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::EC_KEY;
|
||||
fn drop = ffi::EC_KEY_free;
|
||||
|
||||
pub struct EcKey;
|
||||
pub struct EcKeyRef;
|
||||
}
|
||||
|
||||
impl EcKeyRef {
|
||||
private_key_to_pem!(ffi::PEM_write_bio_ECPrivateKey);
|
||||
|
|
@ -355,7 +373,14 @@ impl EcKey {
|
|||
private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey);
|
||||
}
|
||||
|
||||
type_!(EcKeyBuilder, EcKeyBuilderRef, ffi::EC_KEY, ffi::EC_KEY_free);
|
||||
|
||||
foreign_type! {
|
||||
type CType = ffi::EC_KEY;
|
||||
fn drop = ffi::EC_KEY_free;
|
||||
|
||||
pub struct EcKeyBuilder;
|
||||
pub struct EcKeyBuilderRef;
|
||||
}
|
||||
|
||||
impl EcKeyBuilder {
|
||||
pub fn new() -> Result<EcKeyBuilder, ErrorStack> {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[macro_use]
|
||||
extern crate foreign_types;
|
||||
extern crate libc;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
|
|
|||
|
|
@ -1,45 +1,4 @@
|
|||
|
||||
macro_rules! type_ {
|
||||
($n:ident, $r:ident, $c:path, $d:path) => {
|
||||
pub struct $n(*mut $c);
|
||||
|
||||
impl ::types::OpenSslType for $n {
|
||||
type CType = $c;
|
||||
type Ref = $r;
|
||||
|
||||
unsafe fn from_ptr(ptr: *mut $c) -> $n {
|
||||
$n(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for $n {
|
||||
fn drop(&mut self) {
|
||||
unsafe { $d(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for $n {
|
||||
type Target = $r;
|
||||
|
||||
fn deref(&self) -> &$r {
|
||||
unsafe { ::types::OpenSslTypeRef::from_ptr(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::DerefMut for $n {
|
||||
fn deref_mut(&mut self) -> &mut $r {
|
||||
unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct $r(::util::Opaque);
|
||||
|
||||
impl ::types::OpenSslTypeRef for $r {
|
||||
type CType = $c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! private_key_from_pem {
|
||||
($t:ident, $f:path) => {
|
||||
from_pem_inner!(/// Deserializes a PEM-formatted private key.
|
||||
|
|
@ -161,9 +120,11 @@ macro_rules! to_der_inner {
|
|||
#[$m]
|
||||
pub fn $n(&self) -> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let len = try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), ptr::null_mut())));
|
||||
let len = try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
|
||||
ptr::null_mut())));
|
||||
let mut buf = vec![0; len as usize];
|
||||
try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), &mut buf.as_mut_ptr())));
|
||||
try!(::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self),
|
||||
&mut buf.as_mut_ptr())));
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use libc::{c_int, c_long, c_ulong};
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
|
|
@ -8,7 +9,6 @@ use asn1::Asn1GeneralizedTimeRef;
|
|||
use error::ErrorStack;
|
||||
use hash::MessageDigest;
|
||||
use stack::StackRef;
|
||||
use types::OpenSslTypeRef;
|
||||
use x509::store::X509StoreRef;
|
||||
use x509::{X509, X509Ref};
|
||||
|
||||
|
|
@ -135,7 +135,13 @@ impl<'a> Status<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(OcspBasicResponse, OcspBasicResponseRef, ffi::OCSP_BASICRESP, ffi::OCSP_BASICRESP_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::OCSP_BASICRESP;
|
||||
fn drop = ffi::OCSP_BASICRESP_free;
|
||||
|
||||
pub struct OcspBasicResponse;
|
||||
pub struct OcspBasicResponseRef;
|
||||
}
|
||||
|
||||
impl OcspBasicResponseRef {
|
||||
/// Verifies the validity of the response.
|
||||
|
|
@ -189,7 +195,13 @@ impl OcspBasicResponseRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(OcspCertId, OcspCertIdRef, ffi::OCSP_CERTID, ffi::OCSP_CERTID_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::OCSP_CERTID;
|
||||
fn drop = ffi::OCSP_CERTID_free;
|
||||
|
||||
pub struct OcspCertId;
|
||||
pub struct OcspCertIdRef;
|
||||
}
|
||||
|
||||
impl OcspCertId {
|
||||
/// Constructs a certificate ID for certificate `subject`.
|
||||
|
|
@ -204,7 +216,13 @@ impl OcspCertId {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(OcspResponse, OcspResponseRef, ffi::OCSP_RESPONSE, ffi::OCSP_RESPONSE_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::OCSP_RESPONSE;
|
||||
fn drop = ffi::OCSP_RESPONSE_free;
|
||||
|
||||
pub struct OcspResponse;
|
||||
pub struct OcspResponseRef;
|
||||
}
|
||||
|
||||
impl OcspResponse {
|
||||
/// Creates an OCSP response from the status and optional body.
|
||||
|
|
@ -245,7 +263,13 @@ impl OcspResponseRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(OcspRequest, OcspRequestRef, ffi::OCSP_REQUEST, ffi::OCSP_REQUEST_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::OCSP_REQUEST;
|
||||
fn drop = ffi::OCSP_REQUEST_free;
|
||||
|
||||
pub struct OcspRequest;
|
||||
pub struct OcspRequestRef;
|
||||
}
|
||||
|
||||
impl OcspRequest {
|
||||
pub fn new() -> Result<OcspRequest, ErrorStack> {
|
||||
|
|
@ -271,4 +295,10 @@ impl OcspRequestRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(OcspOneReq, OcspOneReqRef, ffi::OCSP_ONEREQ, ffi::OCSP_ONEREQ_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::OCSP_ONEREQ;
|
||||
fn drop = ffi::OCSP_ONEREQ_free;
|
||||
|
||||
pub struct OcspOneReq;
|
||||
pub struct OcspOneReqRef;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! PKCS #12 archives.
|
||||
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use std::ptr;
|
||||
use std::ffi::CString;
|
||||
|
|
@ -9,11 +10,16 @@ use {cvt, cvt_p};
|
|||
use pkey::{PKey, PKeyRef};
|
||||
use error::ErrorStack;
|
||||
use x509::X509;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use stack::Stack;
|
||||
use nid;
|
||||
|
||||
type_!(Pkcs12, Pkcs12Ref, ffi::PKCS12, ffi::PKCS12_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::PKCS12;
|
||||
fn drop = ffi::PKCS12_free;
|
||||
|
||||
pub struct Pkcs12;
|
||||
pub struct Pkcs12Ref;
|
||||
}
|
||||
|
||||
impl Pkcs12Ref {
|
||||
to_der!(ffi::i2d_PKCS12);
|
||||
|
|
|
|||
|
|
@ -2,18 +2,24 @@ use libc::{c_void, c_char, c_int};
|
|||
use std::ptr;
|
||||
use std::mem;
|
||||
use ffi;
|
||||
use foreign_types::{Opaque, ForeignType, ForeignTypeRef};
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use bio::MemBioSlice;
|
||||
use dh::Dh;
|
||||
use dsa::Dsa;
|
||||
use ec::EcKey;
|
||||
use rsa::Rsa;
|
||||
use rsa::{Rsa, Padding};
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb_old};
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
|
||||
type_!(PKey, PKeyRef, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::EVP_PKEY;
|
||||
fn drop = ffi::EVP_PKEY_free;
|
||||
|
||||
pub struct PKey;
|
||||
pub struct PKeyRef;
|
||||
}
|
||||
|
||||
impl PKeyRef {
|
||||
/// Returns a copy of the internal RSA key.
|
||||
|
|
@ -151,6 +157,29 @@ impl PKey {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct PKeyCtxRef(Opaque);
|
||||
|
||||
impl PKeyCtxRef {
|
||||
pub fn set_rsa_padding(&mut self, pad: Padding) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
try!(cvt(ffi::EVP_PKEY_CTX_set_rsa_padding(self.as_ptr(), pad.as_raw())));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rsa_padding(&self) -> Result<Padding, ErrorStack> {
|
||||
let mut pad: c_int = 0;
|
||||
unsafe {
|
||||
try!(cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad)));
|
||||
};
|
||||
Ok(Padding::from_raw(pad))
|
||||
}
|
||||
}
|
||||
|
||||
impl ForeignTypeRef for PKeyCtxRef {
|
||||
type CType = ffi::EVP_PKEY_CTX;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use symm::Cipher;
|
||||
|
|
|
|||
|
|
@ -3,23 +3,39 @@ use std::fmt;
|
|||
use std::ptr;
|
||||
use std::mem;
|
||||
use libc::{c_int, c_void, c_char};
|
||||
use foreign_types::ForeignTypeRef;
|
||||
|
||||
use {cvt, cvt_p, cvt_n};
|
||||
use bn::{BigNum, BigNumRef};
|
||||
use bio::MemBioSlice;
|
||||
use error::ErrorStack;
|
||||
use util::{CallbackState, invoke_passwd_cb_old};
|
||||
use types::OpenSslTypeRef;
|
||||
|
||||
/// Type of encryption padding to use.
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct Padding(c_int);
|
||||
|
||||
impl Padding {
|
||||
pub fn from_raw(value: c_int) -> Padding {
|
||||
Padding(value)
|
||||
}
|
||||
|
||||
pub fn as_raw(&self) -> c_int {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING);
|
||||
pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING);
|
||||
pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
|
||||
|
||||
type_!(Rsa, RsaRef, ffi::RSA, ffi::RSA_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::RSA;
|
||||
fn drop = ffi::RSA_free;
|
||||
|
||||
pub struct Rsa;
|
||||
pub struct RsaRef;
|
||||
}
|
||||
|
||||
impl RsaRef {
|
||||
private_key_to_pem!(ffi::PEM_write_bio_RSAPrivateKey);
|
||||
|
|
@ -343,7 +359,6 @@ mod compat {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use symm::Cipher;
|
||||
|
|
|
|||
|
|
@ -62,27 +62,32 @@
|
|||
//! assert!(memcmp::eq(&hmac, &target));
|
||||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use std::io::{self, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use hash::MessageDigest;
|
||||
use pkey::PKeyRef;
|
||||
use pkey::{PKeyRef, PKeyCtxRef};
|
||||
use error::ErrorStack;
|
||||
use types::OpenSslTypeRef;
|
||||
|
||||
#[cfg(ossl110)]
|
||||
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
|
||||
#[cfg(any(ossl101, ossl102))]
|
||||
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
|
||||
|
||||
pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>);
|
||||
pub struct Signer<'a> {
|
||||
md_ctx: *mut ffi::EVP_MD_CTX,
|
||||
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
|
||||
pkey_pd: PhantomData<&'a PKeyRef>,
|
||||
}
|
||||
|
||||
impl<'a> Drop for Signer<'a> {
|
||||
fn drop(&mut self) {
|
||||
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
|
||||
unsafe {
|
||||
EVP_MD_CTX_free(self.0);
|
||||
EVP_MD_CTX_free(self.md_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -93,8 +98,9 @@ impl<'a> Signer<'a> {
|
|||
ffi::init();
|
||||
|
||||
let ctx = try!(cvt_p(EVP_MD_CTX_new()));
|
||||
let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
|
||||
let r = ffi::EVP_DigestSignInit(ctx,
|
||||
ptr::null_mut(),
|
||||
&mut pctx,
|
||||
type_.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
pkey.as_ptr());
|
||||
|
|
@ -102,22 +108,37 @@ impl<'a> Signer<'a> {
|
|||
EVP_MD_CTX_free(ctx);
|
||||
return Err(ErrorStack::get());
|
||||
}
|
||||
Ok(Signer(ctx, PhantomData))
|
||||
|
||||
assert!(!pctx.is_null());
|
||||
|
||||
Ok(Signer {
|
||||
md_ctx: ctx,
|
||||
pkey_ctx: pctx,
|
||||
pkey_pd: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
|
||||
}
|
||||
|
||||
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
|
||||
}
|
||||
|
||||
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ())
|
||||
cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
unsafe {
|
||||
let mut len = 0;
|
||||
try!(cvt(ffi::EVP_DigestSignFinal(self.0, ptr::null_mut(), &mut len)));
|
||||
try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, ptr::null_mut(), &mut len)));
|
||||
let mut buf = vec![0; len];
|
||||
try!(cvt(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len)));
|
||||
try!(cvt(ffi::EVP_DigestSignFinal(self.md_ctx, buf.as_mut_ptr() as *mut _, &mut len)));
|
||||
// The advertised length is not always equal to the real length for things like DSA
|
||||
buf.truncate(len);
|
||||
Ok(buf)
|
||||
|
|
@ -136,12 +157,17 @@ impl<'a> Write for Signer<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>);
|
||||
pub struct Verifier<'a> {
|
||||
md_ctx: *mut ffi::EVP_MD_CTX,
|
||||
pkey_ctx: *mut ffi::EVP_PKEY_CTX,
|
||||
pkey_pd: PhantomData<&'a PKeyRef>,
|
||||
}
|
||||
|
||||
impl<'a> Drop for Verifier<'a> {
|
||||
fn drop(&mut self) {
|
||||
// pkey_ctx is owned by the md_ctx, so no need to explicitly free it.
|
||||
unsafe {
|
||||
EVP_MD_CTX_free(self.0);
|
||||
EVP_MD_CTX_free(self.md_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -152,8 +178,9 @@ impl<'a> Verifier<'a> {
|
|||
ffi::init();
|
||||
|
||||
let ctx = try!(cvt_p(EVP_MD_CTX_new()));
|
||||
let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut();
|
||||
let r = ffi::EVP_DigestVerifyInit(ctx,
|
||||
ptr::null_mut(),
|
||||
&mut pctx,
|
||||
type_.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
pkey.as_ptr());
|
||||
|
|
@ -162,19 +189,33 @@ impl<'a> Verifier<'a> {
|
|||
return Err(ErrorStack::get());
|
||||
}
|
||||
|
||||
Ok(Verifier(ctx, PhantomData))
|
||||
assert!(!pctx.is_null());
|
||||
|
||||
Ok(Verifier {
|
||||
md_ctx: ctx,
|
||||
pkey_ctx: pctx,
|
||||
pkey_pd: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pkey_ctx(&self) -> &PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr(self.pkey_ctx) }
|
||||
}
|
||||
|
||||
pub fn pkey_ctx_mut(&mut self) -> &mut PKeyCtxRef {
|
||||
unsafe { PKeyCtxRef::from_ptr_mut(self.pkey_ctx) }
|
||||
}
|
||||
|
||||
pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
cvt(ffi::EVP_DigestUpdate(self.0, buf.as_ptr() as *const _, buf.len())).map(|_| ())
|
||||
cvt(ffi::EVP_DigestUpdate(self.md_ctx, buf.as_ptr() as *const _, buf.len())).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let r = EVP_DigestVerifyFinal(self.0, signature.as_ptr() as *const _, signature.len());
|
||||
let r = EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len());
|
||||
match r {
|
||||
1 => Ok(true),
|
||||
0 => {
|
||||
|
|
@ -219,7 +260,7 @@ mod test {
|
|||
use sign::{Signer, Verifier};
|
||||
use ec::{EcGroup, EcKey};
|
||||
use nid;
|
||||
use rsa::Rsa;
|
||||
use rsa::{Rsa, PKCS1_PADDING};
|
||||
use dsa::Dsa;
|
||||
use pkey::PKey;
|
||||
|
||||
|
|
@ -254,6 +295,8 @@ mod test {
|
|||
let pkey = PKey::from_rsa(private_key).unwrap();
|
||||
|
||||
let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
assert_eq!(signer.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
|
||||
signer.pkey_ctx_mut().set_rsa_padding(PKCS1_PADDING).unwrap();
|
||||
signer.update(INPUT).unwrap();
|
||||
let result = signer.finish().unwrap();
|
||||
|
||||
|
|
@ -267,6 +310,7 @@ mod test {
|
|||
let pkey = PKey::from_rsa(private_key).unwrap();
|
||||
|
||||
let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
|
||||
assert_eq!(verifier.pkey_ctx_mut().rsa_padding().unwrap(), PKCS1_PADDING);
|
||||
verifier.update(INPUT).unwrap();
|
||||
assert!(verifier.finish(SIGNATURE).unwrap());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
//! }
|
||||
//! ```
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_int, c_void, c_long, c_ulong};
|
||||
use libc::{c_uchar, c_uint};
|
||||
use std::any::Any;
|
||||
|
|
@ -102,7 +103,6 @@ use x509::store::{X509StoreBuilderRef, X509StoreRef};
|
|||
use verify::X509VerifyParamRef;
|
||||
use pkey::PKeyRef;
|
||||
use error::ErrorStack;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use util::Opaque;
|
||||
use stack::{Stack, StackRef};
|
||||
|
||||
|
|
@ -966,7 +966,13 @@ impl SslContextBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(SslContext, SslContextRef, ffi::SSL_CTX, ffi::SSL_CTX_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::SSL_CTX;
|
||||
fn drop = ffi::SSL_CTX_free;
|
||||
|
||||
pub struct SslContext;
|
||||
pub struct SslContextRef;
|
||||
}
|
||||
|
||||
unsafe impl Send for SslContext {}
|
||||
unsafe impl Sync for SslContext {}
|
||||
|
|
@ -1051,7 +1057,7 @@ pub struct CipherBits {
|
|||
|
||||
pub struct SslCipher(*mut ffi::SSL_CIPHER);
|
||||
|
||||
impl OpenSslType for SslCipher {
|
||||
impl ForeignType for SslCipher {
|
||||
type CType = ffi::SSL_CIPHER;
|
||||
type Ref = SslCipherRef;
|
||||
|
||||
|
|
@ -1076,7 +1082,7 @@ impl DerefMut for SslCipher {
|
|||
|
||||
pub struct SslCipherRef(Opaque);
|
||||
|
||||
impl OpenSslTypeRef for SslCipherRef {
|
||||
impl ForeignTypeRef for SslCipherRef {
|
||||
type CType = ffi::SSL_CIPHER;
|
||||
}
|
||||
|
||||
|
|
@ -1124,7 +1130,13 @@ impl SslCipherRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(SslSession, SslSessionRef, ffi::SSL_SESSION, ffi::SSL_SESSION_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::SSL_SESSION;
|
||||
fn drop = ffi::SSL_SESSION_free;
|
||||
|
||||
pub struct SslSession;
|
||||
pub struct SslSessionRef;
|
||||
}
|
||||
|
||||
impl SslSessionRef {
|
||||
/// Returns the SSL session ID.
|
||||
|
|
@ -1149,7 +1161,13 @@ impl SslSessionRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(Ssl, SslRef, ffi::SSL, ffi::SSL_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::SSL;
|
||||
fn drop = ffi::SSL_free;
|
||||
|
||||
pub struct Ssl;
|
||||
pub struct SslRef;
|
||||
}
|
||||
|
||||
impl fmt::Debug for SslRef {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ macro_rules! run_test(
|
|||
use hash::MessageDigest;
|
||||
use x509::X509StoreContext;
|
||||
use hex::FromHex;
|
||||
use types::OpenSslTypeRef;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use super::Server;
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||
use std::iter;
|
||||
use foreign_types::{ForeignTypeRef, ForeignType};
|
||||
use libc::c_int;
|
||||
use std::borrow::Borrow;
|
||||
use std::convert::AsRef;
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
use libc::c_int;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use util::Opaque;
|
||||
|
||||
#[cfg(ossl10x)]
|
||||
|
|
@ -17,9 +17,8 @@ use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPE
|
|||
|
||||
/// Trait implemented by types which can be placed in a stack.
|
||||
///
|
||||
/// Like `OpenSslType`, it should not be implemented for any type outside
|
||||
/// of this crate.
|
||||
pub trait Stackable: OpenSslType {
|
||||
/// It should not be implemented for any type outside of this crate.
|
||||
pub trait Stackable: ForeignType {
|
||||
/// The C stack type for this element.
|
||||
///
|
||||
/// Generally called `stack_st_{ELEMENT_TYPE}`, normally hidden by the
|
||||
|
|
@ -72,7 +71,7 @@ impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Stackable> OpenSslType for Stack<T> {
|
||||
impl<T: Stackable> ForeignType for Stack<T> {
|
||||
type CType = T::StackType;
|
||||
type Ref = StackRef<T>;
|
||||
|
||||
|
|
@ -140,7 +139,7 @@ impl<T: Stackable> ExactSizeIterator for IntoIter<T> {}
|
|||
|
||||
pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
|
||||
|
||||
impl<T: Stackable> OpenSslTypeRef for StackRef<T> {
|
||||
impl<T: Stackable> ForeignTypeRef for StackRef<T> {
|
||||
type CType = T::StackType;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,20 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_char, c_void};
|
||||
use std::fmt;
|
||||
use std::ffi::CStr;
|
||||
use std::ops::Deref;
|
||||
use std::str;
|
||||
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use stack::Stackable;
|
||||
|
||||
type_!(OpensslString, OpensslStringRef, c_char, free);
|
||||
foreign_type! {
|
||||
type CType = c_char;
|
||||
fn drop = free;
|
||||
|
||||
pub struct OpensslString;
|
||||
pub struct OpensslStringRef;
|
||||
}
|
||||
|
||||
impl OpensslString {
|
||||
#[deprecated(note = "use from_ptr", since = "0.9.7")]
|
||||
|
|
|
|||
|
|
@ -1,40 +1,5 @@
|
|||
//! Items used by other types.
|
||||
#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
|
||||
pub use foreign_types::ForeignType as OpenSslType;
|
||||
|
||||
/// A type implemented by wrappers over OpenSSL types.
|
||||
///
|
||||
/// This should not be implemented by anything outside of this crate; new methods may be added at
|
||||
/// any time.
|
||||
pub trait OpenSslType: Sized {
|
||||
/// The raw C type.
|
||||
type CType;
|
||||
|
||||
/// The type representing a reference to this type.
|
||||
type Ref: OpenSslTypeRef<CType = Self::CType>;
|
||||
|
||||
/// Constructs an instance of this type from its raw type.
|
||||
unsafe fn from_ptr(ptr: *mut Self::CType) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implemented by types which reference borrowed OpenSSL types.
|
||||
///
|
||||
/// This should not be implemented by anything outside of this crate; new methods may be added at
|
||||
/// any time.
|
||||
pub trait OpenSslTypeRef: Sized {
|
||||
/// The raw C type.
|
||||
type CType;
|
||||
|
||||
/// Constructs a shared instance of this type from its raw type.
|
||||
unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
|
||||
&*(ptr as *mut _)
|
||||
}
|
||||
|
||||
/// Constructs a mutable reference of this type from its raw type.
|
||||
unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
|
||||
&mut *(ptr as *mut _)
|
||||
}
|
||||
|
||||
/// Returns a raw pointer to the wrapped value.
|
||||
fn as_ptr(&self) -> *mut Self::CType {
|
||||
self as *const _ as *mut _
|
||||
}
|
||||
}
|
||||
#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
|
||||
pub use foreign_types::ForeignTypeRef as OpenSslTypeRef;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use libc::c_uint;
|
||||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
|
||||
use cvt;
|
||||
use error::ErrorStack;
|
||||
use types::OpenSslTypeRef;
|
||||
|
||||
bitflags! {
|
||||
pub flags X509CheckFlags: c_uint {
|
||||
|
|
@ -19,7 +19,13 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(X509VerifyParam, X509VerifyParamRef, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_VERIFY_PARAM;
|
||||
fn drop = ffi::X509_VERIFY_PARAM_free;
|
||||
|
||||
pub struct X509VerifyParam;
|
||||
pub struct X509VerifyParamRef;
|
||||
}
|
||||
|
||||
impl X509VerifyParamRef {
|
||||
pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::{c_char, c_int, c_long, c_ulong};
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -17,9 +19,7 @@ use hash::MessageDigest;
|
|||
use pkey::{PKey, PKeyRef};
|
||||
use rand::rand_bytes;
|
||||
use error::ErrorStack;
|
||||
use ffi;
|
||||
use nid::Nid;
|
||||
use types::{OpenSslType, OpenSslTypeRef};
|
||||
use string::OpensslString;
|
||||
use stack::{Stack, StackRef, Stackable};
|
||||
|
||||
|
|
@ -53,7 +53,13 @@ pub const X509_FILETYPE_PEM: X509FileType = X509FileType(ffi::X509_FILETYPE_PEM)
|
|||
pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1);
|
||||
pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT);
|
||||
|
||||
type_!(X509StoreContext, X509StoreContextRef, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_STORE_CTX;
|
||||
fn drop = ffi::X509_STORE_CTX_free;
|
||||
|
||||
pub struct X509StoreContext;
|
||||
pub struct X509StoreContextRef;
|
||||
}
|
||||
|
||||
impl X509StoreContextRef {
|
||||
pub fn error(&self) -> Option<X509VerifyError> {
|
||||
|
|
@ -354,7 +360,13 @@ impl X509Generator {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(X509, X509Ref, ffi::X509, ffi::X509_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509;
|
||||
fn drop = ffi::X509_free;
|
||||
|
||||
pub struct X509;
|
||||
pub struct X509Ref;
|
||||
}
|
||||
|
||||
impl X509Ref {
|
||||
pub fn subject_name(&self) -> &X509NameRef {
|
||||
|
|
@ -513,7 +525,13 @@ impl Stackable for X509 {
|
|||
type StackType = ffi::stack_st_X509;
|
||||
}
|
||||
|
||||
type_!(X509Name, X509NameRef, ffi::X509_NAME, ffi::X509_NAME_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_NAME;
|
||||
fn drop = ffi::X509_NAME_free;
|
||||
|
||||
pub struct X509Name;
|
||||
pub struct X509NameRef;
|
||||
}
|
||||
|
||||
impl X509Name {
|
||||
/// Loads subject names from a file containing PEM-formatted certificates.
|
||||
|
|
@ -567,7 +585,13 @@ impl<'a> Iterator for X509NameEntries<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(X509NameEntry, X509NameEntryRef, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_NAME_ENTRY;
|
||||
fn drop = ffi::X509_NAME_ENTRY_free;
|
||||
|
||||
pub struct X509NameEntry;
|
||||
pub struct X509NameEntryRef;
|
||||
}
|
||||
|
||||
impl X509NameEntryRef {
|
||||
pub fn data(&self) -> &Asn1StringRef {
|
||||
|
|
@ -578,7 +602,13 @@ impl X509NameEntryRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(X509Req, X509ReqRef, ffi::X509_REQ, ffi::X509_REQ_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_REQ;
|
||||
fn drop = ffi::X509_REQ_free;
|
||||
|
||||
pub struct X509Req;
|
||||
pub struct X509ReqRef;
|
||||
}
|
||||
|
||||
impl X509Req {
|
||||
/// Reads CSR from PEM
|
||||
|
|
@ -751,7 +781,13 @@ impl X509VerifyError {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(GeneralName, GeneralNameRef, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::GENERAL_NAME;
|
||||
fn drop = ffi::GENERAL_NAME_free;
|
||||
|
||||
pub struct GeneralName;
|
||||
pub struct GeneralNameRef;
|
||||
}
|
||||
|
||||
impl GeneralNameRef {
|
||||
/// Returns the contents of this `GeneralName` if it is a `dNSName`.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
use ffi;
|
||||
use foreign_types::ForeignTypeRef;
|
||||
use std::mem;
|
||||
|
||||
use {cvt, cvt_p};
|
||||
use error::ErrorStack;
|
||||
use types::OpenSslTypeRef;
|
||||
use x509::X509;
|
||||
|
||||
type_!(X509StoreBuilder, X509StoreBuilderRef, ffi::X509_STORE, ffi::X509_STORE_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
pub struct X509StoreBuilder;
|
||||
pub struct X509StoreBuilderRef;
|
||||
}
|
||||
|
||||
impl X509StoreBuilder {
|
||||
/// Returns a builder for a certificate store.
|
||||
|
|
@ -50,4 +56,10 @@ impl X509StoreBuilderRef {
|
|||
}
|
||||
}
|
||||
|
||||
type_!(X509Store, X509StoreRef, ffi::X509_STORE, ffi::X509_STORE_free);
|
||||
foreign_type! {
|
||||
type CType = ffi::X509_STORE;
|
||||
fn drop = ffi::X509_STORE_free;
|
||||
|
||||
pub struct X509Store;
|
||||
pub struct X509StoreRef;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue