Merge branch 'master' into x509_req_version_subject

This commit is contained in:
mredlek 2017-02-07 20:41:27 +01:00
commit 30a634c877
26 changed files with 520 additions and 336 deletions

View File

@ -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:

View File

@ -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

View File

@ -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"

View File

@ -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") {
let libs = match version {
Version::Openssl101 | Version::Openssl102 if target.contains("windows") => {
["ssleay32", "libeay32"]
} else if target.contains("windows") {
["libssl", "libcrypto"]
} else {
["ssl", "crypto"]
}
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 {
for include in lib.include_paths.iter() {
println!("cargo:include={}", include.display());
}
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!("
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.
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
@ -208,149 +280,44 @@ 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:version=101");
} else if version_text.contains("0x10002") {
println!("cargo:rustc-cfg=ossl102");
println!("cargo:version=102");
} else if version_text.contains("0x10100") {
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:conf={}", enabled.join(","));
if expanded.contains("RUST_LIBRESSL") {
println!("cargo:rustc-cfg=libressl");
println!("cargo:libressl=true");
println!("cargo:version=101");
}
Version::Libressl
} else if expanded.contains("RUST_OPENSSL_110") {
println!("cargo:rustc-cfg=ossl110");
println!("cargo:version=110");
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

View File

@ -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;

View File

@ -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" }

View File

@ -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> {

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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> {

View File

@ -2,6 +2,8 @@
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate foreign_types;
extern crate libc;
#[macro_use]
extern crate lazy_static;

View File

@ -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)
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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());
}

View File

@ -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 {

View File

@ -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]

View File

@ -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;
}

View File

@ -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")]

View File

@ -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;

View File

@ -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) {

View File

@ -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`.

View File

@ -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;
}