Remove deprecated APIs

This commit is contained in:
Steven Fackler 2017-12-25 22:02:41 -07:00
parent ff9fe6fe04
commit 2adf2cf12b
18 changed files with 58 additions and 902 deletions

View File

@ -1,6 +0,0 @@
#![doc(hidden)]
#![deprecated(since = "0.9.20")]
use string::OpensslString;
#[deprecated(note = "renamed to OpensslString", since = "0.9.7")]
pub type CryptoString = OpensslString;

View File

@ -7,15 +7,13 @@
use ffi;
use foreign_types::ForeignTypeRef;
use libc::{c_char, c_int, c_void};
use libc::c_int;
use std::fmt;
use std::ptr;
use {cvt, cvt_p};
use bio::MemBioSlice;
use bn::BigNumRef;
use error::ErrorStack;
use util::{invoke_passwd_cb_old, CallbackState};
foreign_type_and_impl_send_sync! {
type CType = ffi::DSA;
@ -158,27 +156,6 @@ impl Dsa {
private_key_from_der!(Dsa, ffi::d2i_DSAPrivateKey);
public_key_from_pem!(Dsa, ffi::PEM_read_bio_DSA_PUBKEY);
public_key_from_der!(Dsa, ffi::d2i_DSAPublicKey);
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = MemBioSlice::new(buf)?;
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
let dsa = cvt_p(ffi::PEM_read_bio_DSAPrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr,
))?;
Ok(Dsa(dsa))
}
}
}
impl fmt::Debug for Dsa {

View File

@ -639,11 +639,6 @@ impl EcKey {
Ok(builder.build())
}
#[deprecated(since = "0.9.2", note = "use from_curve_name")]
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
EcKey::from_curve_name(nid)
}
private_key_from_pem!(EcKey, ffi::PEM_read_bio_ECPrivateKey);
private_key_from_der!(EcKey, ffi::d2i_ECPrivateKey);
}

View File

@ -1,4 +0,0 @@
#![doc(hidden)]
#![deprecated(since = "0.9.2", note = "renamed to `ec`")]
pub use ec::{EcKey, EcKeyRef};

View File

@ -5,7 +5,7 @@ use std::fmt;
use ffi;
#[cfg(ossl110)]
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
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};
@ -70,7 +70,7 @@ use self::State::*;
/// let data = b"\x42\xF4\x97\xE0";
/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2";
/// let res = hash(MessageDigest::md5(), data).unwrap();
/// assert_eq!(res, spec);
/// assert_eq!(&*res, spec);
/// ```
///
/// Supply the input in chunks:
@ -84,7 +84,7 @@ use self::State::*;
/// h.update(data[0]).unwrap();
/// h.update(data[1]).unwrap();
/// let res = h.finish().unwrap();
/// assert_eq!(res, spec);
/// assert_eq!(&*res, spec);
/// ```
///
/// # Warning
@ -120,7 +120,7 @@ impl Hasher {
match self.state {
Reset => return Ok(()),
Updated => {
self.finish2()?;
self.finish()?;
}
Finalized => (),
}
@ -147,15 +147,8 @@ impl Hasher {
Ok(())
}
#[deprecated(note = "use finish2 instead", since = "0.9.11")]
pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
self.finish2().map(|b| b.to_vec())
}
/// Returns the hash of the data written and resets the hasher.
///
/// Unlike `finish`, this method does not allocate.
pub fn finish2(&mut self) -> Result<DigestBytes, ErrorStack> {
pub fn finish(&mut self) -> Result<DigestBytes, ErrorStack> {
if self.state == Finalized {
self.init()?;
}
@ -210,7 +203,7 @@ impl Drop for Hasher {
fn drop(&mut self) {
unsafe {
if self.state != Finalized {
drop(self.finish2());
drop(self.finish());
}
EVP_MD_CTX_free(self.ctx);
}
@ -263,18 +256,11 @@ impl fmt::Debug for DigestBytes {
}
}
#[deprecated(note = "use hash2 instead", since = "0.9.11")]
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
hash2(t, data).map(|b| b.to_vec())
}
/// Computes the hash of the `data` with the hash `t`.
///
/// Unlike `hash`, this function does not allocate the return value.
pub fn hash2(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes, ErrorStack> {
let mut h = Hasher::new(t)?;
h.update(data)?;
h.finish2()
h.finish()
}
#[cfg(test)]
@ -285,20 +271,19 @@ mod tests {
use super::*;
fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let res = hash2(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
let _ = h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap();
let res = h.finish2().unwrap();
let res = h.finish().unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
// Test vectors from http://www.nsrl.nist.gov/testdata/
#[allow(non_upper_case_globals)]
const md5_tests: [(&'static str, &'static str); 13] =
[
const md5_tests: [(&'static str, &'static str); 13] = [
("", "d41d8cd98f00b204e9800998ecf8427e"),
("7F", "83acb6e67e50e31db6ed341dd2de1595"),
("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"),
@ -337,9 +322,9 @@ mod tests {
let mut h = Hasher::new(MessageDigest::md5()).unwrap();
h.write_all(&Vec::from_hex(md5_tests[6].0).unwrap())
.unwrap();
h.finish2().unwrap();
let res = h.finish2().unwrap();
let null = hash2(MessageDigest::md5(), &[]).unwrap();
h.finish().unwrap();
let res = h.finish().unwrap();
let null = hash(MessageDigest::md5(), &[]).unwrap();
assert_eq!(&*res, &*null);
}
@ -358,18 +343,18 @@ mod tests {
println!("Clone an updated hasher");
let mut h2 = h1.clone();
h2.write_all(&inp[p..]).unwrap();
let res = h2.finish2().unwrap();
let res = h2.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
}
h1.write_all(&inp[p..]).unwrap();
let res = h1.finish2().unwrap();
let res = h1.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
println!("Clone a finished hasher");
let mut h3 = h1.clone();
h3.write_all(&Vec::from_hex(md5_tests[i + 1].0).unwrap())
.unwrap();
let res = h3.finish2().unwrap();
let res = h3.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i + 1].1);
}

View File

@ -4,17 +4,17 @@
extern crate bitflags;
#[macro_use]
extern crate foreign_types;
extern crate libc;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate openssl_sys as ffi;
#[cfg(test)]
extern crate data_encoding;
#[cfg(test)]
extern crate hex;
#[cfg(test)]
extern crate tempdir;
#[cfg(test)]
extern crate data_encoding;
#[doc(inline)]
pub use ffi::init;
@ -35,11 +35,9 @@ pub mod bn;
#[cfg(not(libressl))]
pub mod cms;
pub mod conf;
pub mod crypto;
pub mod dh;
pub mod dsa;
pub mod ec;
pub mod ec_key;
pub mod error;
pub mod ex_data;
pub mod hash;
@ -57,7 +55,6 @@ pub mod ssl;
pub mod stack;
pub mod string;
pub mod symm;
pub mod types;
pub mod version;
pub mod x509;
#[cfg(any(ossl102, ossl110))]
@ -80,5 +77,9 @@ fn cvt(r: c_int) -> Result<c_int, ErrorStack> {
}
fn cvt_n(r: c_int) -> Result<c_int, ErrorStack> {
if r < 0 { Err(ErrorStack::get()) } else { Ok(r) }
if r < 0 {
Err(ErrorStack::get())
} else {
Ok(r)
}
}

View File

@ -1,4 +1,4 @@
use libc::{c_char, c_int, c_void, size_t};
use libc::{c_int, size_t};
use std::ptr;
use std::mem;
use std::ffi::CString;
@ -12,7 +12,7 @@ use dsa::Dsa;
use ec::EcKey;
use rsa::{Padding, Rsa};
use error::ErrorStack;
use util::{invoke_passwd_cb, invoke_passwd_cb_old, CallbackState};
use util::{invoke_passwd_cb, CallbackState};
foreign_type_and_impl_send_sync! {
type CType = ffi::EVP_PKEY;
@ -202,25 +202,6 @@ impl PKey {
)).map(PKey)
}
}
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = MemBioSlice::new(buf)?;
unsafe {
let evp = cvt_p(ffi::PEM_read_bio_PrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
&mut cb as *mut _ as *mut c_void,
))?;
Ok(PKey::from_ptr(evp))
}
}
}
foreign_type_and_impl_send_sync! {

View File

@ -2,14 +2,12 @@ use ffi;
use std::fmt;
use std::ptr;
use std::mem;
use libc::{c_char, c_int, c_void};
use libc::c_int;
use foreign_types::ForeignTypeRef;
use {cvt, cvt_n, cvt_p};
use bn::{BigNum, BigNumRef};
use bio::MemBioSlice;
use error::ErrorStack;
use util::{invoke_passwd_cb_old, CallbackState};
/// Type of encryption padding to use.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -329,27 +327,6 @@ impl Rsa {
Rsa,
ffi::d2i_RSAPublicKey
);
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
where
F: FnOnce(&mut [c_char]) -> usize,
{
ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = MemBioSlice::new(buf)?;
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
let rsa = cvt_p(ffi::PEM_read_bio_RSAPrivateKey(
mem_bio.as_ptr(),
ptr::null_mut(),
Some(invoke_passwd_cb_old::<F>),
cb_ptr,
))?;
Ok(Rsa(rsa))
}
}
}
impl fmt::Debug for Rsa {

View File

@ -26,7 +26,7 @@
//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
//! signer.update(data).unwrap();
//! signer.update(data2).unwrap();
//! let signature = signer.finish().unwrap();
//! let signature = signer.sign_to_vec().unwrap();
//!
//! // Verify the data
//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
@ -202,11 +202,6 @@ impl<'a> Signer<'a> {
buf.truncate(len);
Ok(buf)
}
#[deprecated(since = "0.9.23", note = "renamed to sign_to_vec")]
pub fn finish(&self) -> Result<Vec<u8>, ErrorStack> {
self.sign_to_vec()
}
}
impl<'a> Write for Signer<'a> {
@ -314,11 +309,6 @@ impl<'a> Verifier<'a> {
}
}
}
#[deprecated(since = "0.9.23", note = "renamed to `verify`")]
pub fn finish(&self, signature: &[u8]) -> Result<bool, ErrorStack> {
self.verify(signature)
}
}
impl<'a> Write for Verifier<'a> {

View File

@ -10,7 +10,7 @@ use foreign_types::ForeignTypeRef;
use error::ErrorStack;
use dh::Dh;
#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))]
use ec_key::EcKey;
use ec::EcKey;
use ssl::{get_callback_idx, get_ssl_callback_idx, SniError, SslRef, NPN_PROTOS_IDX};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
use ssl::ALPN_PROTOS_IDX;

View File

@ -72,18 +72,6 @@ impl SslConnectorBuilder {
Ok(SslConnectorBuilder(ctx))
}
#[deprecated(since = "0.9.23",
note = "SslConnectorBuilder now implements Deref<Target=SslContextBuilder>")]
pub fn builder(&self) -> &SslContextBuilder {
self
}
#[deprecated(since = "0.9.23",
note = "SslConnectorBuilder now implements DerefMut<Target=SslContextBuilder>")]
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
self
}
/// Consumes the builder, returning an `SslConnector`.
pub fn build(self) -> SslConnector {
SslConnector(self.0.build())
@ -125,24 +113,6 @@ impl SslConnector {
self.configure()?.connect(domain, stream)
}
#[deprecated(
since = "0.9.24",
note = "use `ConnectConfiguration::verify_hostname` and `ConnectConfiguration::use_server_name_indication` instead")]
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
S,
>(
&self,
stream: S,
) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.configure()?
.use_server_name_indication(false)
.verify_hostname(false)
.connect("", stream)
}
/// Returns a structure allowing for configuration of a single TLS session before connection.
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
Ssl::new(&self.0).map(|ssl| ConnectConfiguration {
@ -161,18 +131,6 @@ pub struct ConnectConfiguration {
}
impl ConnectConfiguration {
#[deprecated(since = "0.9.23",
note = "ConnectConfiguration now implements Deref<Target=SslRef>")]
pub fn ssl(&self) -> &Ssl {
&self.ssl
}
#[deprecated(since = "0.9.23",
note = "ConnectConfiguration now implements DerefMut<Target=SslRef>")]
pub fn ssl_mut(&mut self) -> &mut Ssl {
&mut self.ssl
}
/// Configures the use of Server Name Indication (SNI) when connecting.
///
/// Defaults to `true`.
@ -212,23 +170,6 @@ impl ConnectConfiguration {
self.ssl.connect(stream)
}
#[deprecated(
since = "0.9.24",
note = "use `ConnectConfiguration::verify_hostname` and `ConnectConfiguration::use_server_name_indication` instead")]
pub fn danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication<
S,
>(
self,
stream: S,
) -> Result<SslStream<S>, HandshakeError<S>>
where
S: Read + Write,
{
self.use_server_name_indication(false)
.verify_hostname(false)
.connect("", stream)
}
}
impl Deref for ConnectConfiguration {
@ -343,18 +284,6 @@ impl SslAcceptorBuilder {
Ok(self)
}
#[deprecated(since = "0.9.23",
note = "SslAcceptorBuilder now implements Deref<Target=SslContextBuilder>")]
pub fn builder(&self) -> &SslContextBuilder {
self
}
#[deprecated(since = "0.9.23",
note = "SslAcceptorBuilder now implements DerefMut<Target=SslContextBuilder>")]
pub fn builder_mut(&mut self) -> &mut SslContextBuilder {
self
}
/// Consumes the builder, returning a `SslAcceptor`.
pub fn build(self) -> SslAcceptor {
SslAcceptor(self.0.build())

View File

@ -1263,7 +1263,7 @@ fn tmp_ecdh_callback() {
.unwrap();
ctx.set_tmp_ecdh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
EcKey::new_by_curve_name(Nid::X9_62_PRIME256V1)
EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
});
let ssl = Ssl::new(&ctx.build()).unwrap();
ssl.accept(stream).unwrap();
@ -1332,7 +1332,7 @@ fn tmp_ecdh_callback_ssl() {
let mut ssl = Ssl::new(&ctx.build()).unwrap();
ssl.set_tmp_ecdh_callback(|_, _, _| {
CALLED_BACK.store(true, Ordering::SeqCst);
EcKey::new_by_curve_name(Nid::X9_62_PRIME256V1)
EcKey::from_curve_name(Nid::X9_62_PRIME256V1)
});
ssl.accept(stream).unwrap();
});

View File

@ -1,5 +1,5 @@
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use foreign_types::ForeignTypeRef;
use libc::{c_char, c_void};
use std::fmt;
use std::ffi::CStr;
@ -16,18 +16,6 @@ foreign_type_and_impl_send_sync! {
pub struct OpensslStringRef;
}
impl OpensslString {
#[deprecated(note = "use from_ptr", since = "0.9.7")]
pub unsafe fn from_raw_parts(buf: *mut u8, _: usize) -> OpensslString {
OpensslString::from_ptr(buf as *mut c_char)
}
#[deprecated(note = "use from_ptr", since = "0.9.7")]
pub unsafe fn from_null_terminated(buf: *mut c_char) -> OpensslString {
OpensslString::from_ptr(buf)
}
}
impl fmt::Display for OpensslString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&**self, f)

View File

@ -1,5 +0,0 @@
#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
pub use foreign_types::ForeignType as OpenSslType;
#[deprecated(note = "use foreign_types instead", since = "0.9.7")]
pub use foreign_types::ForeignTypeRef as OpenSslTypeRef;

View File

@ -1,4 +1,4 @@
use libc::{c_int, c_char, c_void};
use libc::{c_char, c_int, c_void};
use std::any::Any;
use std::panic::{self, AssertUnwindSafe};
use std::slice;
@ -34,31 +34,6 @@ impl<F> Drop for CallbackState<F> {
}
}
pub unsafe extern "C" fn invoke_passwd_cb_old<F>(
buf: *mut c_char,
size: c_int,
_rwflag: c_int,
cb_state: *mut c_void,
) -> c_int
where
F: FnOnce(&mut [c_char]) -> usize,
{
let callback = &mut *(cb_state as *mut CallbackState<F>);
let result = panic::catch_unwind(AssertUnwindSafe(|| {
let pass_slice = slice::from_raw_parts_mut(buf, size as usize);
callback.cb.take().unwrap()(pass_slice)
}));
match result {
Ok(len) => len as c_int,
Err(err) => {
callback.panic = Some(err);
0
}
}
}
/// Password callback function, passed to private key loading functions.
///
/// `cb_state` is expected to be a pointer to a `CallbackState`.

View File

@ -1,239 +1,9 @@
use std::fmt::{self, Write};
use std::fmt::Write;
use error::ErrorStack;
use nid::Nid;
use x509::{X509Extension, X509v3Context};
/// Type-only version of the `Extension` enum.
///
/// See the `Extension` documentation for more information on the different
/// variants.
#[derive(Clone, Hash, PartialEq, Eq)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum ExtensionType {
KeyUsage,
ExtKeyUsage,
SubjectAltName,
IssuerAltName,
OtherNid(Nid),
OtherStr(String),
}
/// A X.509 v3 certificate extension.
///
/// Only one extension of each type is allow in a certificate.
/// See RFC 3280 for more information about extensions.
#[derive(Clone)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum Extension {
/// The purposes of the key contained in the certificate
KeyUsage(Vec<KeyUsageOption>),
/// The extended purposes of the key contained in the certificate
ExtKeyUsage(Vec<ExtKeyUsageOption>),
/// Subject Alternative Names
SubjectAltName(Vec<(AltNameOption, String)>),
/// Issuer Alternative Names
IssuerAltName(Vec<(AltNameOption, String)>),
/// Arbitrary extensions by NID. See `man x509v3_config` for value syntax.
///
/// You must not use this to add extensions which this enum can express directly.
///
/// ```
/// use openssl::x509::extension::Extension::*;
/// use openssl::nid::Nid;
///
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_extension(OtherNid(Nid::BASIC_CONSTRAINTS,"critical,CA:TRUE".to_owned()));
/// ```
OtherNid(Nid, String),
/// Arbitrary extensions by OID string. See `man ASN1_generate_nconf` for value syntax.
///
/// You must not use this to add extensions which this enum can express directly.
///
/// ```
/// use openssl::x509::extension::Extension::*;
///
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_extension(OtherStr("2.999.2".to_owned(),"ASN1:UTF8:example value".to_owned()));
/// ```
OtherStr(String, String),
}
impl Extension {
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn get_type(&self) -> ExtensionType {
match self {
&Extension::KeyUsage(_) => ExtensionType::KeyUsage,
&Extension::ExtKeyUsage(_) => ExtensionType::ExtKeyUsage,
&Extension::SubjectAltName(_) => ExtensionType::SubjectAltName,
&Extension::IssuerAltName(_) => ExtensionType::IssuerAltName,
&Extension::OtherNid(nid, _) => ExtensionType::OtherNid(nid),
&Extension::OtherStr(ref s, _) => ExtensionType::OtherStr(s.clone()),
}
}
}
impl ExtensionType {
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn get_nid(&self) -> Option<Nid> {
match self {
&ExtensionType::KeyUsage => Some(Nid::KEY_USAGE),
&ExtensionType::ExtKeyUsage => Some(Nid::EXT_KEY_USAGE),
&ExtensionType::SubjectAltName => Some(Nid::SUBJECT_ALT_NAME),
&ExtensionType::IssuerAltName => Some(Nid::ISSUER_ALT_NAME),
&ExtensionType::OtherNid(nid) => Some(nid),
&ExtensionType::OtherStr(_) => None,
}
}
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn get_name(&self) -> Option<&str> {
match self {
&ExtensionType::OtherStr(ref s) => Some(s),
_ => None,
}
}
}
// FIXME: This would be nicer as a method on Iterator<Item=ToString>. This can
// eventually be replaced by the successor to std::slice::SliceConcatExt.connect
fn join<I: Iterator<Item = T>, T: ToString>(iter: I, sep: &str) -> String {
iter.enumerate().fold(String::new(), |mut acc, (idx, v)| {
if idx > 0 {
acc.push_str(sep)
};
acc.push_str(&v.to_string());
acc
})
}
impl ToString for Extension {
fn to_string(&self) -> String {
match self {
&Extension::KeyUsage(ref purposes) => join(purposes.iter(), ","),
&Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(), ","),
&Extension::SubjectAltName(ref names) => join(
names
.iter()
.map(|&(ref opt, ref val)| opt.to_string() + ":" + &val),
",",
),
&Extension::IssuerAltName(ref names) => join(
names
.iter()
.map(|&(ref opt, ref val)| opt.to_string() + ":" + &val),
",",
),
&Extension::OtherNid(_, ref value) => value.clone(),
&Extension::OtherStr(_, ref value) => value.clone(),
}
}
}
#[derive(Clone, Copy)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum KeyUsageOption {
DigitalSignature,
NonRepudiation,
KeyEncipherment,
DataEncipherment,
KeyAgreement,
KeyCertSign,
CRLSign,
EncipherOnly,
DecipherOnly,
}
impl fmt::Display for KeyUsageOption {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.pad(match self {
&KeyUsageOption::DigitalSignature => "digitalSignature",
&KeyUsageOption::NonRepudiation => "nonRepudiation",
&KeyUsageOption::KeyEncipherment => "keyEncipherment",
&KeyUsageOption::DataEncipherment => "dataEncipherment",
&KeyUsageOption::KeyAgreement => "keyAgreement",
&KeyUsageOption::KeyCertSign => "keyCertSign",
&KeyUsageOption::CRLSign => "cRLSign",
&KeyUsageOption::EncipherOnly => "encipherOnly",
&KeyUsageOption::DecipherOnly => "decipherOnly",
})
}
}
#[derive(Clone)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum ExtKeyUsageOption {
ServerAuth,
ClientAuth,
CodeSigning,
EmailProtection,
TimeStamping,
MsCodeInd,
MsCodeCom,
MsCtlSign,
MsSgc,
MsEfs,
NsSgc,
/// An arbitrary key usage by OID.
Other(String),
}
impl fmt::Display for ExtKeyUsageOption {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.pad(match self {
&ExtKeyUsageOption::ServerAuth => "serverAuth",
&ExtKeyUsageOption::ClientAuth => "clientAuth",
&ExtKeyUsageOption::CodeSigning => "codeSigning",
&ExtKeyUsageOption::EmailProtection => "emailProtection",
&ExtKeyUsageOption::TimeStamping => "timeStamping",
&ExtKeyUsageOption::MsCodeInd => "msCodeInd",
&ExtKeyUsageOption::MsCodeCom => "msCodeCom",
&ExtKeyUsageOption::MsCtlSign => "msCTLSign",
&ExtKeyUsageOption::MsSgc => "msSGC",
&ExtKeyUsageOption::MsEfs => "msEFS",
&ExtKeyUsageOption::NsSgc => "nsSGC",
&ExtKeyUsageOption::Other(ref s) => &s[..],
})
}
}
#[derive(Clone, Copy)]
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub enum AltNameOption {
/// The value is specified as OID;content. See `man ASN1_generate_nconf` for more information on the content syntax.
///
/// ```
/// use openssl::x509::extension::Extension::*;
/// use openssl::x509::extension::AltNameOption::Other as OtherName;
///
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_extension(SubjectAltName(vec![(OtherName,"2.999.3;ASN1:UTF8:some other name".to_owned())]));
/// ```
Other,
Email,
DNS,
// X400, // Not supported by OpenSSL
Directory,
// EDIParty, // Not supported by OpenSSL
URI,
IPAddress,
RegisteredID,
}
impl fmt::Display for AltNameOption {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.pad(match self {
&AltNameOption::Other => "otherName",
&AltNameOption::Email => "email",
&AltNameOption::DNS => "DNS",
&AltNameOption::Directory => "dirName",
&AltNameOption::URI => "URI",
&AltNameOption::IPAddress => "IP",
&AltNameOption::RegisteredID => "RID",
})
}
}
pub struct BasicConstraints {
critical: bool,
ca: bool,

View File

@ -1,8 +1,6 @@
#![allow(deprecated)]
use libc::{c_int, c_long};
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use std::collections::HashMap;
use std::error::Error;
use std::ffi::{CStr, CString};
use std::fmt;
@ -14,9 +12,8 @@ use std::slice;
use std::str;
use {cvt, cvt_n, cvt_p};
use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1Time, Asn1TimeRef};
use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef};
use bio::MemBioSlice;
use bn::{BigNum, MsbOption};
use conf::ConfRef;
use error::ErrorStack;
use hash::MessageDigest;
@ -36,8 +33,6 @@ use ffi::{ASN1_STRING_get0_data as ASN1_STRING_data,
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub mod verify;
use x509::extension::{Extension, ExtensionType};
pub mod extension;
pub mod store;
@ -110,196 +105,6 @@ impl X509StoreContextRef {
}
}
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub struct X509Generator {
days: u32,
names: Vec<(String, String)>,
extensions: Extensions,
hash_type: MessageDigest,
}
#[allow(deprecated)]
impl X509Generator {
/// Creates a new generator with the following defaults:
///
/// validity period: 365 days
///
/// CN: "rust-openssl"
///
/// hash: SHA1
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn new() -> X509Generator {
X509Generator {
days: 365,
names: vec![],
extensions: Extensions::new(),
hash_type: MessageDigest::sha1(),
}
}
/// Sets certificate validity period in days since today
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn set_valid_period(mut self, days: u32) -> X509Generator {
self.days = days;
self
}
/// Add attribute to the name of the certificate
///
/// ```
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_name("CN".to_string(),"example.com".to_string());
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_name(mut self, attr_type: String, attr_value: String) -> X509Generator {
self.names.push((attr_type, attr_value));
self
}
/// Add multiple attributes to the name of the certificate
///
/// ```
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_names(vec![("CN".to_string(),"example.com".to_string())]);
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_names<I>(mut self, attrs: I) -> X509Generator
where
I: IntoIterator<Item = (String, String)>,
{
self.names.extend(attrs);
self
}
/// Add an extension to a certificate
///
/// If the extension already exists, it will be replaced.
///
/// ```
/// use openssl::x509::extension::Extension::*;
/// use openssl::x509::extension::KeyUsageOption::*;
///
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment]));
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_extension(mut self, ext: extension::Extension) -> X509Generator {
self.extensions.add(ext);
self
}
/// Add multiple extensions to a certificate
///
/// If any of the extensions already exist, they will be replaced.
///
/// ```
/// use openssl::x509::extension::Extension::*;
/// use openssl::x509::extension::KeyUsageOption::*;
///
/// # let generator = openssl::x509::X509Generator::new();
/// generator.add_extensions(vec![KeyUsage(vec![DigitalSignature, KeyEncipherment])]);
/// ```
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn add_extensions<I>(mut self, exts: I) -> X509Generator
where
I: IntoIterator<Item = extension::Extension>,
{
for ext in exts {
self.extensions.add(ext);
}
self
}
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn set_sign_hash(mut self, hash_type: MessageDigest) -> X509Generator {
self.hash_type = hash_type;
self
}
/// Sets the certificate public-key, then self-sign and return it
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn sign(&self, p_key: &PKeyRef) -> Result<X509, ErrorStack> {
let mut builder = X509::builder()?;
builder.set_version(2)?;
let mut serial = BigNum::new()?;
serial.rand(128, MsbOption::MAYBE_ZERO, false)?;
let serial = serial.to_asn1_integer()?;
builder.set_serial_number(&serial)?;
let not_before = Asn1Time::days_from_now(0)?;
builder.set_not_before(&not_before)?;
let not_after = Asn1Time::days_from_now(self.days)?;
builder.set_not_after(&not_after)?;
builder.set_pubkey(p_key)?;
let mut name = X509Name::builder()?;
if self.names.is_empty() {
name.append_entry_by_nid(Nid::COMMONNAME, "rust-openssl")?;
} else {
for &(ref key, ref value) in &self.names {
name.append_entry_by_text(key, value)?;
}
}
let name = name.build();
builder.set_subject_name(&name)?;
builder.set_issuer_name(&name)?;
for (exttype, ext) in self.extensions.iter() {
let extension = match exttype.get_nid() {
Some(nid) => {
let ctx = builder.x509v3_context(None, None);
X509Extension::new_nid(None, Some(&ctx), nid, &ext.to_string())?
}
None => {
let ctx = builder.x509v3_context(None, None);
X509Extension::new(
None,
Some(&ctx),
&exttype.get_name().unwrap(),
&ext.to_string(),
)?
}
};
builder.append_extension(extension)?;
}
builder.sign(p_key, self.hash_type)?;
Ok(builder.build())
}
/// Obtain a certificate signing request (CSR)
#[deprecated(since = "0.9.7", note = "use X509Builder and X509ReqBuilder instead")]
pub fn request(&self, p_key: &PKeyRef) -> Result<X509Req, ErrorStack> {
let cert = match self.sign(p_key) {
Ok(c) => c,
Err(x) => return Err(x),
};
unsafe {
let req = cvt_p(ffi::X509_to_X509_REQ(
cert.as_ptr(),
ptr::null_mut(),
ptr::null(),
))?;
let req = X509Req::from_ptr(req);
let exts = compat::X509_get0_extensions(cert.as_ptr());
if exts != ptr::null_mut() {
cvt(ffi::X509_REQ_add_extensions(req.as_ptr(), exts as *mut _))?;
}
let hash_fn = self.hash_type.as_ptr();
cvt(ffi::X509_REQ_sign(req.as_ptr(), p_key.as_ptr(), hash_fn))?;
Ok(req)
}
}
}
/// A builder type which can create `X509` objects.
pub struct X509Builder(X509);
@ -941,75 +746,6 @@ impl X509ReqRef {
}
}
/// A collection of X.509 extensions.
///
/// Upholds the invariant that a certificate MUST NOT include more than one
/// instance of a particular extension, according to RFC 3280 §4.2. Also
/// ensures that extensions are added to the certificate during signing
/// in the order they were inserted, which is required for certain
/// extensions like SubjectKeyIdentifier and AuthorityKeyIdentifier.
struct Extensions {
/// The extensions contained in the collection.
extensions: Vec<Extension>,
/// A map of used to keep track of added extensions and their indexes in `self.extensions`.
indexes: HashMap<ExtensionType, usize>,
}
impl Extensions {
/// Creates a new `Extensions`.
pub fn new() -> Extensions {
Extensions {
extensions: vec![],
indexes: HashMap::new(),
}
}
/// Adds a new `Extension`, replacing any existing one of the same
/// `ExtensionType`.
pub fn add(&mut self, ext: Extension) {
let ext_type = ext.get_type();
if let Some(index) = self.indexes.get(&ext_type) {
self.extensions[*index] = ext;
return;
}
self.extensions.push(ext);
self.indexes.insert(ext_type, self.extensions.len() - 1);
}
/// Returns an `ExtensionsIter` for the collection.
pub fn iter(&self) -> ExtensionsIter {
ExtensionsIter {
current: 0,
extensions: &self.extensions,
}
}
}
/// An iterator that iterates over `(ExtensionType, Extension)` for each
/// extension in the collection.
struct ExtensionsIter<'a> {
current: usize,
extensions: &'a Vec<Extension>,
}
impl<'a> Iterator for ExtensionsIter<'a> {
type Item = (ExtensionType, &'a Extension);
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.extensions.len() {
let ext = &self.extensions[self.current];
self.current += 1;
Some((ext.get_type(), ext))
} else {
None
}
}
}
pub struct X509VerifyError(c_long);
impl fmt::Debug for X509VerifyError {
@ -1135,7 +871,6 @@ 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_get0_extensions;
pub use ffi::X509_REQ_get_version;
pub use ffi::X509_REQ_get_subject_name;
pub use ffi::X509_get0_signature;
@ -1166,17 +901,6 @@ mod compat {
);
}
pub unsafe fn X509_get0_extensions(
cert: *const ffi::X509,
) -> *const ffi::stack_st_X509_EXTENSION {
let info = (*cert).cert_info;
if info.is_null() {
0 as *mut _
} else {
(*info).extensions
}
}
pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long {
::ffi::ASN1_INTEGER_get((*(*x).req_info).version)
}

View File

@ -2,121 +2,20 @@ use hex::{FromHex, ToHex};
use asn1::Asn1Time;
use bn::{BigNum, MsbOption};
use ec::{Asn1Flag, EcGroup, EcKey};
use hash::MessageDigest;
use nid::Nid;
use pkey::PKey;
use rsa::Rsa;
use stack::Stack;
use x509::{X509, X509Generator, X509Name, X509Req};
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, Extension,
KeyUsage, SubjectAlternativeName, SubjectKeyIdentifier};
use ssl::{SslContextBuilder, SslMethod};
use x509::extension::AltNameOption as SAN;
use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment};
use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth};
fn get_generator() -> X509Generator {
X509Generator::new()
.set_valid_period(365 * 2)
.add_name("CN".to_string(), "test_me".to_string())
.set_sign_hash(MessageDigest::sha1())
.add_extension(Extension::KeyUsage(vec![DigitalSignature, KeyEncipherment]))
.add_extension(Extension::ExtKeyUsage(vec![
ClientAuth,
ServerAuth,
ExtKeyUsageOption::Other("2.999.1".to_owned()),
]))
.add_extension(Extension::SubjectAltName(vec![
(SAN::DNS, "example.com".to_owned()),
]))
.add_extension(Extension::OtherNid(
Nid::BASIC_CONSTRAINTS,
"critical,CA:TRUE".to_owned(),
))
.add_extension(Extension::OtherStr(
"2.999.2".to_owned(),
"ASN1:UTF8:example value".to_owned(),
))
}
use x509::{X509, X509Name, X509Req};
use x509::extension::{AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
SubjectAlternativeName, SubjectKeyIdentifier};
fn pkey() -> PKey {
let rsa = Rsa::generate(2048).unwrap();
PKey::from_rsa(rsa).unwrap()
}
#[test]
fn test_cert_gen() {
let pkey = pkey();
let cert = get_generator().sign(&pkey).unwrap();
// FIXME: check data in result to be correct, needs implementation
// of X509 getters
assert_eq!(
pkey.public_key_to_pem().unwrap(),
cert.public_key().unwrap().public_key_to_pem().unwrap()
);
}
/// SubjectKeyIdentifier must be added before AuthorityKeyIdentifier or OpenSSL
/// is "unable to get issuer keyid." This test ensures the order of insertion
/// for extensions is preserved when the cert is signed.
#[test]
fn test_cert_gen_extension_ordering() {
let pkey = pkey();
get_generator()
.add_extension(Extension::OtherNid(
Nid::SUBJECT_KEY_IDENTIFIER,
"hash".to_owned(),
))
.add_extension(Extension::OtherNid(
Nid::AUTHORITY_KEY_IDENTIFIER,
"keyid:always".to_owned(),
))
.sign(&pkey)
.expect("Failed to generate cert with order-dependent extensions");
}
/// Proves that a passing result from `test_cert_gen_extension_ordering` is
/// deterministic by reversing the order of extensions and asserting failure.
#[test]
fn test_cert_gen_extension_bad_ordering() {
let pkey = pkey();
let result = get_generator()
.add_extension(Extension::OtherNid(
Nid::AUTHORITY_KEY_IDENTIFIER,
"keyid:always".to_owned(),
))
.add_extension(Extension::OtherNid(
Nid::SUBJECT_KEY_IDENTIFIER,
"hash".to_owned(),
))
.sign(&pkey);
assert!(result.is_err());
}
#[test]
fn test_req_gen() {
let pkey = pkey();
let req = get_generator().request(&pkey).unwrap();
let reqpem = req.to_pem().unwrap();
let req = X509Req::from_pem(&reqpem).ok().expect("Failed to load PEM");
let cn = (*req)
.subject_name()
.entries_by_nid(Nid::COMMONNAME)
.next()
.unwrap();
assert_eq!(0, (*req).version());
assert_eq!(cn.data().as_slice(), b"test_me");
// FIXME: check data in result to be correct, needs implementation
// of X509_REQ getters
}
#[test]
fn test_cert_loading() {
let cert = include_bytes!("../../test/cert.pem");
@ -358,26 +257,6 @@ fn issued() {
cert.issued(&cert).err().unwrap();
}
#[test]
fn ecdsa_cert() {
let mut group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap();
group.set_asn1_flag(Asn1Flag::NAMED_CURVE);
let key = EcKey::generate(&group).unwrap();
let key = PKey::from_ec_key(key).unwrap();
let cert = X509Generator::new()
.set_valid_period(365)
.add_name("CN".to_owned(), "TestServer".to_owned())
.set_sign_hash(MessageDigest::sha256())
.sign(&key)
.unwrap();
let mut ctx = SslContextBuilder::new(SslMethod::tls()).unwrap();
ctx.set_certificate(&cert).unwrap();
ctx.set_private_key(&key).unwrap();
ctx.check_private_key().unwrap();
}
#[test]
fn signature() {
let cert = include_bytes!("../../test/cert.pem");