Merge pull request #475 from sfackler/no-enums

Turn enums into structs
This commit is contained in:
Steven Fackler 2016-10-15 17:03:17 -07:00 committed by GitHub
commit fdb4131064
16 changed files with 439 additions and 404 deletions

View File

@ -6,6 +6,7 @@ dist: trusty
env: env:
global: global:
- TARGET=x86_64-unknown-linux-gnu - TARGET=x86_64-unknown-linux-gnu
- BUILD_OPENSSL_VERSION=1.0.1u
matrix: matrix:
include: include:
# ARM-bit version compat # ARM-bit version compat
@ -44,7 +45,6 @@ matrix:
- rust: nightly - rust: nightly
# 64-bit version compat # 64-bit version compat
- env: BUILD_OPENSSL_VERSION=1.0.1u
- env: BUILD_OPENSSL_VERSION=1.0.2h - env: BUILD_OPENSSL_VERSION=1.0.2h
- env: BUILD_OPENSSL_VERSION=1.1.0b - env: BUILD_OPENSSL_VERSION=1.1.0b

View File

@ -110,6 +110,7 @@ pub const CRYPTO_LOCK: c_int = 1;
pub const EVP_MAX_MD_SIZE: c_uint = 64; pub const EVP_MAX_MD_SIZE: c_uint = 64;
pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption;
pub const EVP_PKEY_HMAC: c_int = NID_hmac; pub const EVP_PKEY_HMAC: c_int = NID_hmac;
pub const EVP_PKEY_DSA: c_int = NID_dsa;
pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2;
@ -120,6 +121,7 @@ pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG;
pub const NID_rsaEncryption: c_int = 6; pub const NID_rsaEncryption: c_int = 6;
pub const NID_ext_key_usage: c_int = 126; pub const NID_ext_key_usage: c_int = 126;
pub const NID_key_usage: c_int = 83; pub const NID_key_usage: c_int = 83;
pub const NID_dsa: c_int = 116;
pub const NID_hmac: c_int = 855; pub const NID_hmac: c_int = 855;
pub const PKCS5_SALT_LEN: c_int = 8; pub const PKCS5_SALT_LEN: c_int = 8;

View File

@ -2,16 +2,14 @@ use ffi;
use std::fmt; use std::fmt;
use error::ErrorStack; use error::ErrorStack;
use std::ptr; use std::ptr;
use libc::{c_uint, c_int, c_char, c_void}; use libc::{c_int, c_char, c_void};
use bn::BigNumRef; use bn::BigNumRef;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use crypto::hash;
use HashTypeInternals;
use crypto::util::{CallbackState, invoke_passwd_cb}; use crypto::util::{CallbackState, invoke_passwd_cb};
/// Builder for upfront DSA parameter generateration /// Builder for upfront DSA parameter generation
pub struct DSAParams(*mut ffi::DSA); pub struct DSAParams(*mut ffi::DSA);
impl DSAParams { impl DSAParams {
@ -156,39 +154,6 @@ impl DSA {
} }
} }
pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, ErrorStack> {
let k_len = self.size().expect("DSA missing a q") as c_uint;
let mut sig = vec![0; k_len as usize];
let mut sig_len = k_len;
assert!(self.has_private_key());
unsafe {
try_ssl!(ffi::DSA_sign(hash.as_nid() as c_int,
message.as_ptr(),
message.len() as c_int,
sig.as_mut_ptr(),
&mut sig_len,
self.0));
sig.set_len(sig_len as usize);
sig.shrink_to_fit();
Ok(sig)
}
}
pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
unsafe {
let result = ffi::DSA_verify(hash.as_nid() as c_int,
message.as_ptr(),
message.len() as c_int,
sig.as_ptr(),
sig.len() as c_int,
self.0);
try_ssl_if!(result == -1);
Ok(result == 1)
}
}
pub fn as_ptr(&self) -> *mut ffi::DSA { pub fn as_ptr(&self) -> *mut ffi::DSA {
self.0 self.0
} }
@ -282,76 +247,7 @@ mod test {
#[test] #[test]
pub fn test_generate() { pub fn test_generate() {
let key = DSA::generate(1024).unwrap(); DSA::generate(1024).unwrap();
key.public_key_to_pem().unwrap();
key.private_key_to_pem().unwrap();
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let digest = {
let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
sha.finish().unwrap()
};
let sig = key.sign(Type::SHA1, &digest).unwrap();
let verified = key.verify(Type::SHA1, &digest, &sig).unwrap();
assert!(verified);
}
#[test]
pub fn test_sign_verify() {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
let key = include_bytes!("../../test/dsa.pem");
DSA::private_key_from_pem(key).unwrap()
};
let public_key = {
let key = include_bytes!("../../test/dsa.pem.pub");
DSA::public_key_from_pem(key).unwrap()
};
let digest = {
let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
sha.finish().unwrap()
};
let sig = private_key.sign(Type::SHA1, &digest).unwrap();
let verified = public_key.verify(Type::SHA1, &digest, &sig).unwrap();
assert!(verified);
}
#[test]
pub fn test_sign_verify_fail() {
let input: Vec<u8> = (0..25).cycle().take(128).collect();
let private_key = {
let key = include_bytes!("../../test/dsa.pem");
DSA::private_key_from_pem(key).unwrap()
};
let public_key = {
let key = include_bytes!("../../test/dsa.pem.pub");
DSA::public_key_from_pem(key).unwrap()
};
let digest = {
let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
sha.finish().unwrap()
};
let mut sig = private_key.sign(Type::SHA1, &digest).unwrap();
// tamper with the sig this should cause a failure
let len = sig.len();
sig[len / 2] = 0;
sig[len - 1] = 0;
if let Ok(true) = public_key.verify(Type::SHA1, &digest, &sig) {
panic!("Tampered with signatures should not verify!");
}
} }
#[test] #[test]

View File

@ -8,47 +8,56 @@ use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
#[cfg(any(ossl101, ossl102))] #[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};
use HashTypeInternals;
use error::ErrorStack; use error::ErrorStack;
use nid::Nid;
/// Message digest (hash) type.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Type { pub struct MessageDigest(*const ffi::EVP_MD);
MD5,
SHA1,
SHA224,
SHA256,
SHA384,
SHA512,
RIPEMD160,
}
impl HashTypeInternals for Type { impl MessageDigest {
fn as_nid(&self) -> Nid { pub fn md5() -> MessageDigest {
match *self {
Type::MD5 => Nid::MD5,
Type::SHA1 => Nid::SHA1,
Type::SHA224 => Nid::SHA224,
Type::SHA256 => Nid::SHA256,
Type::SHA384 => Nid::SHA384,
Type::SHA512 => Nid::SHA512,
Type::RIPEMD160 => Nid::RIPEMD160,
}
}
fn evp_md(&self) -> *const ffi::EVP_MD {
unsafe { unsafe {
match *self { MessageDigest(ffi::EVP_md5())
Type::MD5 => ffi::EVP_md5(),
Type::SHA1 => ffi::EVP_sha1(),
Type::SHA224 => ffi::EVP_sha224(),
Type::SHA256 => ffi::EVP_sha256(),
Type::SHA384 => ffi::EVP_sha384(),
Type::SHA512 => ffi::EVP_sha512(),
Type::RIPEMD160 => ffi::EVP_ripemd160(),
} }
} }
pub fn sha1() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_sha1())
}
}
pub fn sha224() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_sha224())
}
}
pub fn sha256() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_sha256())
}
}
pub fn sha384() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_sha384())
}
}
pub fn sha512() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_sha512())
}
}
pub fn ripemd160() -> MessageDigest {
unsafe {
MessageDigest(ffi::EVP_ripemd160())
}
}
pub fn as_ptr(&self) -> *const ffi::EVP_MD {
self.0
} }
} }
@ -68,20 +77,22 @@ use self::State::*;
/// Calculate a hash in one go. /// Calculate a hash in one go.
/// ///
/// ``` /// ```
/// use openssl::crypto::hash::{hash, Type}; /// use openssl::crypto::hash::{hash, MessageDigest};
///
/// let data = b"\x42\xF4\x97\xE0"; /// 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 spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2";
/// let res = hash(Type::MD5, data).unwrap(); /// let res = hash(MessageDigest::md5(), data).unwrap();
/// assert_eq!(res, spec); /// assert_eq!(res, spec);
/// ``` /// ```
/// ///
/// Use the `Write` trait to supply the input in chunks. /// Use the `Write` trait to supply the input in chunks.
/// ///
/// ``` /// ```
/// use openssl::crypto::hash::{Hasher, Type}; /// use openssl::crypto::hash::{Hasher, MessageDigest};
///
/// let data = [b"\x42\xF4", b"\x97\xE0"]; /// let data = [b"\x42\xF4", b"\x97\xE0"];
/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; /// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2";
/// let mut h = Hasher::new(Type::MD5).unwrap(); /// let mut h = Hasher::new(MessageDigest::md5()).unwrap();
/// h.update(data[0]).unwrap(); /// h.update(data[0]).unwrap();
/// h.update(data[1]).unwrap(); /// h.update(data[1]).unwrap();
/// let res = h.finish().unwrap(); /// let res = h.finish().unwrap();
@ -96,21 +107,20 @@ use self::State::*;
pub struct Hasher { pub struct Hasher {
ctx: *mut ffi::EVP_MD_CTX, ctx: *mut ffi::EVP_MD_CTX,
md: *const ffi::EVP_MD, md: *const ffi::EVP_MD,
type_: Type, type_: MessageDigest,
state: State, state: State,
} }
impl Hasher { impl Hasher {
/// Creates a new `Hasher` with the specified hash type. /// Creates a new `Hasher` with the specified hash type.
pub fn new(ty: Type) -> Result<Hasher, ErrorStack> { pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> {
ffi::init(); ffi::init();
let ctx = unsafe { try_ssl_null!(EVP_MD_CTX_new()) }; let ctx = unsafe { try_ssl_null!(EVP_MD_CTX_new()) };
let md = ty.evp_md();
let mut h = Hasher { let mut h = Hasher {
ctx: ctx, ctx: ctx,
md: md, md: ty.as_ptr(),
type_: ty, type_: ty,
state: Finalized, state: Finalized,
}; };
@ -204,7 +214,7 @@ impl Drop for Hasher {
} }
/// Computes the hash of the `data` with the hash `t`. /// Computes the hash of the `data` with the hash `t`.
pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> { pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
let mut h = try!(Hasher::new(t)); let mut h = try!(Hasher::new(t));
try!(h.update(data)); try!(h.update(data));
h.finish() h.finish()
@ -213,10 +223,10 @@ pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serialize::hex::{FromHex, ToHex}; use serialize::hex::{FromHex, ToHex};
use super::{hash, Hasher, Type}; use super::{hash, Hasher, MessageDigest};
use std::io::prelude::*; use std::io::prelude::*;
fn hash_test(hashtype: Type, hashtest: &(&str, &str)) { fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
let res = hash(hashtype, &*hashtest.0.from_hex().unwrap()).unwrap(); let res = hash(hashtype, &*hashtest.0.from_hex().unwrap()).unwrap();
assert_eq!(res.to_hex(), hashtest.1); assert_eq!(res.to_hex(), hashtest.1);
} }
@ -259,13 +269,13 @@ mod tests {
#[test] #[test]
fn test_md5() { fn test_md5() {
for test in md5_tests.iter() { for test in md5_tests.iter() {
hash_test(Type::MD5, test); hash_test(MessageDigest::md5(), test);
} }
} }
#[test] #[test]
fn test_md5_recycle() { fn test_md5_recycle() {
let mut h = Hasher::new(Type::MD5).unwrap(); let mut h = Hasher::new(MessageDigest::md5()).unwrap();
for test in md5_tests.iter() { for test in md5_tests.iter() {
hash_recycle_test(&mut h, test); hash_recycle_test(&mut h, test);
} }
@ -273,11 +283,11 @@ mod tests {
#[test] #[test]
fn test_finish_twice() { fn test_finish_twice() {
let mut h = Hasher::new(Type::MD5).unwrap(); let mut h = Hasher::new(MessageDigest::md5()).unwrap();
h.write_all(&*md5_tests[6].0.from_hex().unwrap()).unwrap(); h.write_all(&*md5_tests[6].0.from_hex().unwrap()).unwrap();
h.finish().unwrap(); h.finish().unwrap();
let res = h.finish().unwrap(); let res = h.finish().unwrap();
let null = hash(Type::MD5, &[]).unwrap(); let null = hash(MessageDigest::md5(), &[]).unwrap();
assert_eq!(res, null); assert_eq!(res, null);
} }
@ -287,7 +297,7 @@ mod tests {
let inp = md5_tests[i].0.from_hex().unwrap(); let inp = md5_tests[i].0.from_hex().unwrap();
assert!(inp.len() > 2); assert!(inp.len() > 2);
let p = inp.len() / 2; let p = inp.len() / 2;
let h0 = Hasher::new(Type::MD5).unwrap(); let h0 = Hasher::new(MessageDigest::md5()).unwrap();
println!("Clone a new hasher"); println!("Clone a new hasher");
let mut h1 = h0.clone(); let mut h1 = h0.clone();
@ -315,7 +325,7 @@ mod tests {
let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")]; let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")];
for test in tests.iter() { for test in tests.iter() {
hash_test(Type::SHA1, test); hash_test(MessageDigest::sha1(), test);
} }
} }
@ -325,7 +335,7 @@ mod tests {
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")]; "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")];
for test in tests.iter() { for test in tests.iter() {
hash_test(Type::SHA256, test); hash_test(MessageDigest::sha256(), test);
} }
} }
@ -334,7 +344,7 @@ mod tests {
let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")]; let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")];
for test in tests.iter() { for test in tests.iter() {
hash_test(Type::RIPEMD160, test); hash_test(MessageDigest::ripemd160(), test);
} }
} }
} }

View File

@ -97,7 +97,7 @@ mod compat {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crypto::hash::Type::SHA1; use crypto::hash::MessageDigest;
use serialize::hex::ToHex; use serialize::hex::ToHex;
use super::*; use super::*;
@ -108,11 +108,11 @@ mod test {
let pkcs12 = Pkcs12::from_der(der).unwrap(); let pkcs12 = Pkcs12::from_der(der).unwrap();
let parsed = pkcs12.parse("mypass").unwrap(); let parsed = pkcs12.parse("mypass").unwrap();
assert_eq!(parsed.cert.fingerprint(SHA1).unwrap().to_hex(), assert_eq!(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"59172d9313e84459bcff27f967e79e6e9217e584"); "59172d9313e84459bcff27f967e79e6e9217e584");
assert_eq!(parsed.chain.len(), 1); assert_eq!(parsed.chain.len(), 1);
assert_eq!(parsed.chain[0].fingerprint(SHA1).unwrap().to_hex(), assert_eq!(parsed.chain[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
"c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"); "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
} }
} }

View File

@ -2,9 +2,8 @@ use libc::c_int;
use std::ptr; use std::ptr;
use ffi; use ffi;
use HashTypeInternals; use crypto::hash::MessageDigest;
use crypto::hash; use crypto::symm::Cipher;
use crypto::symm;
use error::ErrorStack; use error::ErrorStack;
#[derive(Clone, Eq, PartialEq, Hash, Debug)] #[derive(Clone, Eq, PartialEq, Hash, Debug)]
@ -23,8 +22,8 @@ pub struct KeyIvPair {
/// ///
/// New applications should not use this and instead use `pbkdf2_hmac_sha1` or /// New applications should not use this and instead use `pbkdf2_hmac_sha1` or
/// another more modern key derivation algorithm. /// another more modern key derivation algorithm.
pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, pub fn evp_bytes_to_key_pbkdf1_compatible(cipher: Cipher,
message_digest_type: hash::Type, digest: MessageDigest,
data: &[u8], data: &[u8],
salt: Option<&[u8]>, salt: Option<&[u8]>,
count: u32) count: u32)
@ -40,11 +39,11 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type,
ffi::init(); ffi::init();
let typ = typ.as_ptr(); let cipher = cipher.as_ptr();
let message_digest_type = message_digest_type.evp_md(); let digest = digest.as_ptr();
let len = ffi::EVP_BytesToKey(typ, let len = ffi::EVP_BytesToKey(cipher,
message_digest_type, digest,
salt_ptr, salt_ptr,
data.as_ptr(), data.as_ptr(),
data.len() as c_int, data.len() as c_int,
@ -58,8 +57,8 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type,
let mut key = vec![0; len as usize]; let mut key = vec![0; len as usize];
let mut iv = vec![0; len as usize]; let mut iv = vec![0; len as usize];
try_ssl!(ffi::EVP_BytesToKey(typ, try_ssl!(ffi::EVP_BytesToKey(cipher,
message_digest_type, digest,
salt_ptr, salt_ptr,
data.as_ptr(), data.as_ptr(),
data.len() as c_int, data.len() as c_int,
@ -97,7 +96,7 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8],
pub fn pbkdf2_hmac(pass: &[u8], pub fn pbkdf2_hmac(pass: &[u8],
salt: &[u8], salt: &[u8],
iter: usize, iter: usize,
hash: hash::Type, hash: MessageDigest,
keylen: usize) keylen: usize)
-> Result<Vec<u8>, ErrorStack> { -> Result<Vec<u8>, ErrorStack> {
unsafe { unsafe {
@ -108,7 +107,7 @@ pub fn pbkdf2_hmac(pass: &[u8],
salt.as_ptr(), salt.as_ptr(),
salt.len() as c_int, salt.len() as c_int,
iter as c_int, iter as c_int,
hash.evp_md(), hash.as_ptr(),
keylen as c_int, keylen as c_int,
out.as_mut_ptr())); out.as_mut_ptr()));
Ok(out) Ok(out)
@ -117,8 +116,8 @@ pub fn pbkdf2_hmac(pass: &[u8],
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crypto::hash; use crypto::hash::MessageDigest;
use crypto::symm; use crypto::symm::Cipher;
// Test vectors from // Test vectors from
// http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06
@ -162,11 +161,11 @@ mod tests {
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
#[test] #[test]
fn test_pbkdf2_hmac_sha256() { fn test_pbkdf2_hmac_sha256() {
assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, hash::Type::SHA256, 16).unwrap(), assert_eq!(super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), 16).unwrap(),
vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, vec![0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8,
0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8]); 0xec_u8, 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8]);
assert_eq!(super::pbkdf2_hmac(b"Password", b"NaCl", 80000, hash::Type::SHA256, 16).unwrap(), assert_eq!(super::pbkdf2_hmac(b"Password", b"NaCl", 80000, MessageDigest::sha256(), 16).unwrap(),
vec![0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, vec![0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8,
0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8]); 0x83_u8, 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8]);
} }
@ -175,7 +174,7 @@ mod tests {
// https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c
#[test] #[test]
fn test_pbkdf2_hmac_sha512() { fn test_pbkdf2_hmac_sha512() {
assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, hash::Type::SHA512, 64).unwrap(), assert_eq!(super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), 64).unwrap(),
vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, vec![0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8,
0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, 0x94_u8, 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8,
0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, 0xd3_u8, 0xc7_u8, 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8,
@ -185,7 +184,7 @@ mod tests {
0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8, 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, 0x5e_u8, 0x9f_u8,
0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8]); 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, 0x06_u8]);
assert_eq!(super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, hash::Type::SHA512, 64).unwrap(), assert_eq!(super::pbkdf2_hmac(b"pass\0word", b"sa\0lt", 1, MessageDigest::sha512(), 64).unwrap(),
vec![0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, vec![0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8,
0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, 0x8b_u8, 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8,
0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, 0x2f_u8, 0x93_u8, 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8,
@ -198,7 +197,7 @@ mod tests {
assert_eq!(super::pbkdf2_hmac(b"passwordPASSWORDpassword", assert_eq!(super::pbkdf2_hmac(b"passwordPASSWORDpassword",
b"salt\0\0\0", b"salt\0\0\0",
50, 50,
hash::Type::SHA512, MessageDigest::sha512(),
64).unwrap(), 64).unwrap(),
vec![0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, vec![0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8,
0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, 0x85_u8, 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8,
@ -229,8 +228,8 @@ mod tests {
0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8,
0_u8, 0_u8, 0_u8]; 0_u8, 0_u8, 0_u8];
assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(symm::Type::AES_256_CBC, assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(Cipher::aes_256_cbc(),
hash::Type::SHA1, MessageDigest::sha1(),
&data, &data,
Some(&salt), Some(&salt),
1).unwrap(), 1).unwrap(),

View File

@ -4,6 +4,7 @@ use std::mem;
use ffi; use ffi;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use crypto::dsa::DSA;
use crypto::rsa::RSA; use crypto::rsa::RSA;
use error::ErrorStack; use error::ErrorStack;
use crypto::util::{CallbackState, invoke_passwd_cb}; use crypto::util::{CallbackState, invoke_passwd_cb};
@ -26,6 +27,17 @@ impl PKey {
} }
} }
/// Create a new `PKey` containing a DSA key.
pub fn from_dsa(dsa: DSA) -> Result<PKey, ErrorStack> {
unsafe {
let evp = try_ssl_null!(ffi::EVP_PKEY_new());
let pkey = PKey(evp);
try_ssl!(ffi::EVP_PKEY_assign(pkey.0, ffi::EVP_PKEY_DSA, dsa.as_ptr() as *mut _));
mem::forget(dsa);
Ok(pkey)
}
}
/// Create a new `PKey` containing an HMAC key. /// Create a new `PKey` containing an HMAC key.
pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> { pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> {
unsafe { unsafe {

View File

@ -11,19 +11,19 @@ use crypto::util::{CallbackState, invoke_passwd_cb};
/// Type of encryption padding to use. /// Type of encryption padding to use.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Padding { pub struct Padding(c_int);
None,
OAEP,
PKCS1v15
}
impl Padding { impl Padding {
fn openssl_padding_code(&self) -> c_int { pub fn none() -> Padding {
match *self { Padding(ffi::RSA_NO_PADDING)
Padding::None => ffi::RSA_NO_PADDING,
Padding::OAEP => ffi::RSA_PKCS1_OAEP_PADDING,
Padding::PKCS1v15 => ffi::RSA_PKCS1_PADDING
} }
pub fn pkcs1() -> Padding {
Padding(ffi::RSA_PKCS1_PADDING)
}
pub fn pkcs1_oaep() -> Padding {
Padding(ffi::RSA_PKCS1_OAEP_PADDING)
} }
} }
@ -183,7 +183,7 @@ impl RSA {
from.as_ptr(), from.as_ptr(),
to.as_mut_ptr(), to.as_mut_ptr(),
self.0, self.0,
padding.openssl_padding_code())); padding.0));
to.truncate(enc_len as usize); to.truncate(enc_len as usize);
Ok(to) Ok(to)
} }
@ -202,7 +202,7 @@ impl RSA {
from.as_ptr(), from.as_ptr(),
to.as_mut_ptr(), to.as_mut_ptr(),
self.0, self.0,
padding.openssl_padding_code())); padding.0));
assert!(enc_len as u32 == k_len); assert!(enc_len as u32 == k_len);
Ok(to) Ok(to)
@ -221,7 +221,7 @@ impl RSA {
from.as_ptr(), from.as_ptr(),
to.as_mut_ptr(), to.as_mut_ptr(),
self.0, self.0,
padding.openssl_padding_code())); padding.0));
to.truncate(enc_len as usize); to.truncate(enc_len as usize);
Ok(to) Ok(to)
} }
@ -239,7 +239,7 @@ impl RSA {
from.as_ptr(), from.as_ptr(),
to.as_mut_ptr(), to.as_mut_ptr(),
self.0, self.0,
padding.openssl_padding_code())); padding.0));
assert!(enc_len as u32 == k_len); assert!(enc_len as u32 == k_len);
Ok(to) Ok(to)
@ -425,13 +425,13 @@ mod test {
let public_key = RSA::public_key_from_pem(key).unwrap(); let public_key = RSA::public_key_from_pem(key).unwrap();
let original_data: Vec<u8> = "This is test".to_string().into_bytes(); let original_data: Vec<u8> = "This is test".to_string().into_bytes();
let result = public_key.public_encrypt(&original_data, Padding::PKCS1v15).unwrap(); let result = public_key.public_encrypt(&original_data, Padding::pkcs1()).unwrap();
assert_eq!(result.len(), 256); assert_eq!(result.len(), 256);
let pkey = include_bytes!("../../test/rsa.pem"); let pkey = include_bytes!("../../test/rsa.pem");
let private_key = RSA::private_key_from_pem(pkey).unwrap(); let private_key = RSA::private_key_from_pem(pkey).unwrap();
let dec_result = private_key.private_decrypt(&result, Padding::PKCS1v15).unwrap(); let dec_result = private_key.private_decrypt(&result, Padding::pkcs1()).unwrap();
assert_eq!(dec_result, original_data); assert_eq!(dec_result, original_data);
} }
@ -444,8 +444,8 @@ mod test {
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
let emsg = k0.private_encrypt(&msg, Padding::PKCS1v15).unwrap(); let emsg = k0.private_encrypt(&msg, Padding::pkcs1()).unwrap();
let dmsg = k1.public_decrypt(&emsg, Padding::PKCS1v15).unwrap(); let dmsg = k1.public_decrypt(&emsg, Padding::pkcs1()).unwrap();
assert!(msg == dmsg); assert!(msg == dmsg);
} }
@ -457,8 +457,8 @@ mod test {
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
let emsg = k1.public_encrypt(&msg, Padding::OAEP).unwrap(); let emsg = k1.public_encrypt(&msg, Padding::pkcs1_oaep()).unwrap();
let dmsg = k0.private_decrypt(&emsg, Padding::OAEP).unwrap(); let dmsg = k0.private_decrypt(&emsg, Padding::pkcs1_oaep()).unwrap();
assert!(msg == dmsg); assert!(msg == dmsg);
} }
@ -470,8 +470,8 @@ mod test {
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
let emsg = k1.public_encrypt(&msg, super::Padding::PKCS1v15).unwrap(); let emsg = k1.public_encrypt(&msg, super::Padding::pkcs1()).unwrap();
let dmsg = k0.private_decrypt(&emsg, super::Padding::PKCS1v15).unwrap(); let dmsg = k0.private_decrypt(&emsg, super::Padding::pkcs1()).unwrap();
assert!(msg == dmsg); assert!(msg == dmsg);
} }

View File

@ -13,7 +13,7 @@
//! use openssl::crypto::sign::{Signer, Verifier}; //! use openssl::crypto::sign::{Signer, Verifier};
//! use openssl::crypto::rsa::RSA; //! use openssl::crypto::rsa::RSA;
//! use openssl::crypto::pkey::PKey; //! use openssl::crypto::pkey::PKey;
//! use openssl::crypto::hash::Type; //! use openssl::crypto::hash::MessageDigest;
//! //!
//! // Generate a keypair //! // Generate a keypair
//! let keypair = RSA::generate(2048).unwrap(); //! let keypair = RSA::generate(2048).unwrap();
@ -23,13 +23,13 @@
//! let data2 = b"hola, mundo!"; //! let data2 = b"hola, mundo!";
//! //!
//! // Sign the data //! // Sign the data
//! let mut signer = Signer::new(Type::SHA256, &keypair).unwrap(); //! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap();
//! signer.update(data).unwrap(); //! signer.update(data).unwrap();
//! signer.update(data2).unwrap(); //! signer.update(data2).unwrap();
//! let signature = signer.finish().unwrap(); //! let signature = signer.finish().unwrap();
//! //!
//! // Verify the data //! // Verify the data
//! let mut verifier = Verifier::new(Type::SHA256, &keypair).unwrap(); //! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap();
//! verifier.update(data).unwrap(); //! verifier.update(data).unwrap();
//! verifier.update(data2).unwrap(); //! verifier.update(data2).unwrap();
//! assert!(verifier.finish(&signature).unwrap()); //! assert!(verifier.finish(&signature).unwrap());
@ -40,7 +40,7 @@
//! ```rust //! ```rust
//! use openssl::crypto::sign::Signer; //! use openssl::crypto::sign::Signer;
//! use openssl::crypto::pkey::PKey; //! use openssl::crypto::pkey::PKey;
//! use openssl::crypto::hash::Type; //! use openssl::crypto::hash::MessageDigest;
//! //!
//! // Create a PKey //! // Create a PKey
//! let key = PKey::hmac(b"my secret").unwrap(); //! let key = PKey::hmac(b"my secret").unwrap();
@ -49,7 +49,7 @@
//! let data2 = b"hola, mundo!"; //! let data2 = b"hola, mundo!";
//! //!
//! // Compute the HMAC //! // Compute the HMAC
//! let mut signer = Signer::new(Type::SHA256, &key).unwrap(); //! let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap();
//! signer.update(data).unwrap(); //! signer.update(data).unwrap();
//! signer.update(data2).unwrap(); //! signer.update(data2).unwrap();
//! let hmac = signer.finish().unwrap(); //! let hmac = signer.finish().unwrap();
@ -59,8 +59,7 @@ use std::io::{self, Write};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr; use std::ptr;
use HashTypeInternals; use crypto::hash::MessageDigest;
use crypto::hash::Type;
use crypto::pkey::PKey; use crypto::pkey::PKey;
use error::ErrorStack; use error::ErrorStack;
@ -80,14 +79,14 @@ impl<'a> Drop for Signer<'a> {
} }
impl<'a> Signer<'a> { impl<'a> Signer<'a> {
pub fn new(type_: Type, pkey: &'a PKey) -> Result<Signer<'a>, ErrorStack> { pub fn new(type_: MessageDigest, pkey: &'a PKey) -> Result<Signer<'a>, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
let ctx = try_ssl_null!(EVP_MD_CTX_new()); let ctx = try_ssl_null!(EVP_MD_CTX_new());
let r = ffi::EVP_DigestSignInit(ctx, let r = ffi::EVP_DigestSignInit(ctx,
ptr::null_mut(), ptr::null_mut(),
type_.evp_md(), type_.as_ptr(),
ptr::null_mut(), ptr::null_mut(),
pkey.as_ptr()); pkey.as_ptr());
if r != 1 { if r != 1 {
@ -113,6 +112,8 @@ impl<'a> Signer<'a> {
let mut buf = vec![0; len]; let mut buf = vec![0; len];
try_ssl_if!(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len) try_ssl_if!(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len)
!= 1); != 1);
// The advertised length is not always equal to the real length for things like DSA
buf.truncate(len);
Ok(buf) Ok(buf)
} }
} }
@ -140,14 +141,14 @@ impl<'a> Drop for Verifier<'a> {
} }
impl<'a> Verifier<'a> { impl<'a> Verifier<'a> {
pub fn new(type_: Type, pkey: &'a PKey) -> Result<Verifier<'a>, ErrorStack> { pub fn new(type_: MessageDigest, pkey: &'a PKey) -> Result<Verifier<'a>, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
let ctx = try_ssl_null!(EVP_MD_CTX_new()); let ctx = try_ssl_null!(EVP_MD_CTX_new());
let r = ffi::EVP_DigestVerifyInit(ctx, let r = ffi::EVP_DigestVerifyInit(ctx,
ptr::null_mut(), ptr::null_mut(),
type_.evp_md(), type_.as_ptr(),
ptr::null_mut(), ptr::null_mut(),
pkey.as_ptr()); pkey.as_ptr());
if r != 1 { if r != 1 {
@ -210,9 +211,10 @@ mod test {
use serialize::hex::FromHex; use serialize::hex::FromHex;
use std::iter; use std::iter;
use crypto::hash::Type; use crypto::hash::MessageDigest;
use crypto::sign::{Signer, Verifier}; use crypto::sign::{Signer, Verifier};
use crypto::rsa::RSA; use crypto::rsa::RSA;
use crypto::dsa::DSA;
use crypto::pkey::PKey; use crypto::pkey::PKey;
static INPUT: &'static [u8] = static INPUT: &'static [u8] =
@ -240,12 +242,12 @@ mod test {
112, 223, 200, 163, 42, 70, 149, 67, 208, 25, 238, 251, 71]; 112, 223, 200, 163, 42, 70, 149, 67, 208, 25, 238, 251, 71];
#[test] #[test]
fn test_sign() { fn rsa_sign() {
let key = include_bytes!("../../test/rsa.pem"); let key = include_bytes!("../../test/rsa.pem");
let private_key = RSA::private_key_from_pem(key).unwrap(); let private_key = RSA::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(private_key).unwrap(); let pkey = PKey::from_rsa(private_key).unwrap();
let mut signer = Signer::new(Type::SHA256, &pkey).unwrap(); let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap();
signer.update(INPUT).unwrap(); signer.update(INPUT).unwrap();
let result = signer.finish().unwrap(); let result = signer.finish().unwrap();
@ -253,29 +255,79 @@ mod test {
} }
#[test] #[test]
fn test_verify_ok() { fn rsa_verify_ok() {
let key = include_bytes!("../../test/rsa.pem"); let key = include_bytes!("../../test/rsa.pem");
let private_key = RSA::private_key_from_pem(key).unwrap(); let private_key = RSA::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(private_key).unwrap(); let pkey = PKey::from_rsa(private_key).unwrap();
let mut verifier = Verifier::new(Type::SHA256, &pkey).unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
verifier.update(INPUT).unwrap(); verifier.update(INPUT).unwrap();
assert!(verifier.finish(SIGNATURE).unwrap()); assert!(verifier.finish(SIGNATURE).unwrap());
} }
#[test] #[test]
fn test_verify_invalid() { fn rsa_verify_invalid() {
let key = include_bytes!("../../test/rsa.pem"); let key = include_bytes!("../../test/rsa.pem");
let private_key = RSA::private_key_from_pem(key).unwrap(); let private_key = RSA::private_key_from_pem(key).unwrap();
let pkey = PKey::from_rsa(private_key).unwrap(); let pkey = PKey::from_rsa(private_key).unwrap();
let mut verifier = Verifier::new(Type::SHA256, &pkey).unwrap(); let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap();
verifier.update(INPUT).unwrap(); verifier.update(INPUT).unwrap();
verifier.update(b"foobar").unwrap(); verifier.update(b"foobar").unwrap();
assert!(!verifier.finish(SIGNATURE).unwrap()); assert!(!verifier.finish(SIGNATURE).unwrap());
} }
fn test_hmac(ty: Type, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) { #[test]
pub fn dsa_sign_verify() {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
let key = include_bytes!("../../test/dsa.pem");
PKey::from_dsa(DSA::private_key_from_pem(key).unwrap()).unwrap()
};
let public_key = {
let key = include_bytes!("../../test/dsa.pem.pub");
PKey::from_dsa(DSA::public_key_from_pem(key).unwrap()).unwrap()
};
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
signer.update(&input).unwrap();
let sig = signer.finish().unwrap();
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
verifier.update(&input).unwrap();
assert!(verifier.finish(&sig).unwrap());
}
#[test]
pub fn dsa_sign_verify_fail() {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
let key = include_bytes!("../../test/dsa.pem");
PKey::from_dsa(DSA::private_key_from_pem(key).unwrap()).unwrap()
};
let public_key = {
let key = include_bytes!("../../test/dsa.pem.pub");
PKey::from_dsa(DSA::public_key_from_pem(key).unwrap()).unwrap()
};
let mut signer = Signer::new(MessageDigest::sha1(), &private_key).unwrap();
signer.update(&input).unwrap();
let mut sig = signer.finish().unwrap();
sig[0] -= 1;
let mut verifier = Verifier::new(MessageDigest::sha1(), &public_key).unwrap();
verifier.update(&input).unwrap();
match verifier.finish(&sig) {
Ok(true) => panic!("unexpected success"),
Ok(false) | Err(_) => {},
}
}
fn test_hmac(ty: MessageDigest, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
for &(ref key, ref data, ref res) in tests.iter() { for &(ref key, ref data, ref res) in tests.iter() {
let pkey = PKey::hmac(key).unwrap(); let pkey = PKey::hmac(key).unwrap();
let mut signer = Signer::new(ty, &pkey).unwrap(); let mut signer = Signer::new(ty, &pkey).unwrap();
@ -312,7 +364,7 @@ mod test {
.to_vec(), .to_vec(),
"6f630fad67cda0ee1fb1f562db3aa53e".from_hex().unwrap())]; "6f630fad67cda0ee1fb1f562db3aa53e".from_hex().unwrap())];
test_hmac(Type::MD5, &tests); test_hmac(MessageDigest::md5(), &tests);
} }
#[test] #[test]
@ -343,6 +395,6 @@ mod test {
.to_vec(), .to_vec(),
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91".from_hex().unwrap())]; "e8e99d0f45237d786d6bbaa7965c7808bbff1a91".from_hex().unwrap())];
test_hmac(Type::SHA1, &tests); test_hmac(MessageDigest::sha1(), &tests);
} }
} }

View File

@ -11,57 +11,120 @@ pub enum Mode {
Decrypt, Decrypt,
} }
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Type { pub struct Cipher(*const ffi::EVP_CIPHER);
AES_128_ECB,
AES_128_CBC,
AES_128_XTS,
AES_128_CTR,
AES_128_CFB1,
AES_128_CFB128,
AES_128_CFB8,
AES_256_ECB,
AES_256_CBC,
AES_256_XTS,
AES_256_CTR,
AES_256_CFB1,
AES_256_CFB128,
AES_256_CFB8,
DES_CBC,
DES_ECB,
RC4_128,
}
impl Type { impl Cipher {
pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER { pub fn aes_128_ecb() -> Cipher {
unsafe { unsafe {
match *self { Cipher(ffi::EVP_aes_128_ecb())
Type::AES_128_ECB => ffi::EVP_aes_128_ecb(),
Type::AES_128_CBC => ffi::EVP_aes_128_cbc(),
Type::AES_128_XTS => ffi::EVP_aes_128_xts(),
Type::AES_128_CTR => ffi::EVP_aes_128_ctr(),
Type::AES_128_CFB1 => ffi::EVP_aes_128_cfb1(),
Type::AES_128_CFB128 => ffi::EVP_aes_128_cfb128(),
Type::AES_128_CFB8 => ffi::EVP_aes_128_cfb8(),
Type::AES_256_ECB => ffi::EVP_aes_256_ecb(),
Type::AES_256_CBC => ffi::EVP_aes_256_cbc(),
Type::AES_256_XTS => ffi::EVP_aes_256_xts(),
Type::AES_256_CTR => ffi::EVP_aes_256_ctr(),
Type::AES_256_CFB1 => ffi::EVP_aes_256_cfb1(),
Type::AES_256_CFB128 => ffi::EVP_aes_256_cfb128(),
Type::AES_256_CFB8 => ffi::EVP_aes_256_cfb8(),
Type::DES_CBC => ffi::EVP_des_cbc(),
Type::DES_ECB => ffi::EVP_des_ecb(),
Type::RC4_128 => ffi::EVP_rc4(),
} }
} }
pub fn aes_128_cbc() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_cbc())
}
}
pub fn aes_128_xts() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_xts())
}
}
pub fn aes_128_ctr() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_ctr())
}
}
pub fn aes_128_cfb1() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_cfb1())
}
}
pub fn aes_128_cfb128() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_cfb128())
}
}
pub fn aes_128_cfb8() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_128_cfb8())
}
}
pub fn aes_256_ecb() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_ecb())
}
}
pub fn aes_256_cbc() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_cbc())
}
}
pub fn aes_256_xts() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_xts())
}
}
pub fn aes_256_ctr() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_ctr())
}
}
pub fn aes_256_cfb1() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_cfb1())
}
}
pub fn aes_256_cfb128() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_cfb128())
}
}
pub fn aes_256_cfb8() -> Cipher {
unsafe {
Cipher(ffi::EVP_aes_256_cfb8())
}
}
pub fn des_cbc() -> Cipher {
unsafe {
Cipher(ffi::EVP_des_cbc())
}
}
pub fn des_ecb() -> Cipher {
unsafe {
Cipher(ffi::EVP_des_ecb())
}
}
pub fn rc4() -> Cipher {
unsafe {
Cipher(ffi::EVP_rc4())
}
}
pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER {
self.0
} }
/// Returns the length of keys used with this cipher. /// Returns the length of keys used with this cipher.
pub fn key_len(&self) -> usize { pub fn key_len(&self) -> usize {
unsafe { unsafe {
EVP_CIPHER_key_length(self.as_ptr()) as usize EVP_CIPHER_key_length(self.0) as usize
} }
} }
@ -69,7 +132,7 @@ impl Type {
/// cipher does not use an IV. /// cipher does not use an IV.
pub fn iv_len(&self) -> Option<usize> { pub fn iv_len(&self) -> Option<usize> {
unsafe { unsafe {
let len = EVP_CIPHER_iv_length(self.as_ptr()) as usize; let len = EVP_CIPHER_iv_length(self.0) as usize;
if len == 0 { if len == 0 {
None None
} else { } else {
@ -85,7 +148,7 @@ impl Type {
/// Stream ciphers such as RC4 have a block size of 1. /// Stream ciphers such as RC4 have a block size of 1.
pub fn block_size(&self) -> usize { pub fn block_size(&self) -> usize {
unsafe { unsafe {
EVP_CIPHER_block_size(self.as_ptr()) as usize EVP_CIPHER_block_size(self.0) as usize
} }
} }
} }
@ -102,8 +165,8 @@ impl Crypter {
/// # Panics /// # Panics
/// ///
/// Panics if an IV is required by the cipher but not provided, or if the /// Panics if an IV is required by the cipher but not provided, or if the
/// IV's length does not match the expected length (see `Type::iv_len`). /// IV's length does not match the expected length (see `Cipher::iv_len`).
pub fn new(t: Type, mode: Mode, key: &[u8], iv: Option<&[u8]>) -> Result<Crypter, ErrorStack> { pub fn new(t: Cipher, mode: Mode, key: &[u8], iv: Option<&[u8]>) -> Result<Crypter, ErrorStack> {
ffi::init(); ffi::init();
unsafe { unsafe {
@ -165,7 +228,7 @@ impl Crypter {
/// # Panics /// # Panics
/// ///
/// Panics if `output.len() < input.len() + block_size` where /// Panics if `output.len() < input.len() + block_size` where
/// `block_size` is the block size of the cipher (see `Type::block_size`), /// `block_size` is the block size of the cipher (see `Cipher::block_size`),
/// or if `output.len() > c_int::max_value()`. /// or if `output.len() > c_int::max_value()`.
pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> { pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> {
unsafe { unsafe {
@ -218,7 +281,7 @@ impl Drop for Crypter {
* Encrypts data, using the specified crypter type in encrypt mode with the * Encrypts data, using the specified crypter type in encrypt mode with the
* specified key and iv; returns the resulting (encrypted) data. * specified key and iv; returns the resulting (encrypted) data.
*/ */
pub fn encrypt(t: Type, pub fn encrypt(t: Cipher,
key: &[u8], key: &[u8],
iv: Option<&[u8]>, iv: Option<&[u8]>,
data: &[u8]) data: &[u8])
@ -230,7 +293,7 @@ pub fn encrypt(t: Type,
* Decrypts data, using the specified crypter type in decrypt mode with the * Decrypts data, using the specified crypter type in decrypt mode with the
* specified key and iv; returns the resulting (decrypted) data. * specified key and iv; returns the resulting (decrypted) data.
*/ */
pub fn decrypt(t: Type, pub fn decrypt(t: Cipher,
key: &[u8], key: &[u8],
iv: Option<&[u8]>, iv: Option<&[u8]>,
data: &[u8]) data: &[u8])
@ -238,7 +301,7 @@ pub fn decrypt(t: Type,
cipher(t, Mode::Decrypt, key, iv, data) cipher(t, Mode::Decrypt, key, iv, data)
} }
fn cipher(t: Type, fn cipher(t: Cipher,
mode: Mode, mode: Mode,
key: &[u8], key: &[u8],
iv: Option<&[u8]>, iv: Option<&[u8]>,
@ -292,23 +355,23 @@ mod tests {
0xaau8, 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8]; 0xaau8, 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8];
let c0 = [0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, let c0 = [0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8,
0x49u8, 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8]; 0x49u8, 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8];
let mut c = super::Crypter::new(super::Type::AES_256_ECB, let mut c = super::Crypter::new(super::Cipher::aes_256_ecb(),
super::Mode::Encrypt, super::Mode::Encrypt,
&k0, &k0,
None).unwrap(); None).unwrap();
c.pad(false); c.pad(false);
let mut r0 = vec![0; c0.len() + super::Type::AES_256_ECB.block_size()]; let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()];
let count = c.update(&p0, &mut r0).unwrap(); let count = c.update(&p0, &mut r0).unwrap();
let rest = c.finalize(&mut r0[count..]).unwrap(); let rest = c.finalize(&mut r0[count..]).unwrap();
r0.truncate(count + rest); r0.truncate(count + rest);
assert_eq!(r0.to_hex(), c0.to_hex()); assert_eq!(r0.to_hex(), c0.to_hex());
let mut c = super::Crypter::new(super::Type::AES_256_ECB, let mut c = super::Crypter::new(super::Cipher::aes_256_ecb(),
super::Mode::Decrypt, super::Mode::Decrypt,
&k0, &k0,
None).unwrap(); None).unwrap();
c.pad(false); c.pad(false);
let mut p1 = vec![0; r0.len() + super::Type::AES_256_ECB.block_size()]; let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()];
let count = c.update(&r0, &mut p1).unwrap(); let count = c.update(&r0, &mut p1).unwrap();
let rest = c.finalize(&mut p1[count..]).unwrap(); let rest = c.finalize(&mut p1[count..]).unwrap();
p1.truncate(count + rest); p1.truncate(count + rest);
@ -326,12 +389,12 @@ mod tests {
let ciphered_data = [0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, let ciphered_data = [0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8,
0xd7_u8, 0xea_u8, 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0xd7_u8, 0xea_u8, 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8,
0x65_u8, 0x6f_u8]; 0x65_u8, 0x6f_u8];
let mut cr = super::Crypter::new(super::Type::AES_256_CBC, let mut cr = super::Crypter::new(super::Cipher::aes_256_cbc(),
super::Mode::Decrypt, super::Mode::Decrypt,
&data, &data,
Some(&iv)).unwrap(); Some(&iv)).unwrap();
cr.pad(false); cr.pad(false);
let mut unciphered_data = vec![0; data.len() + super::Type::AES_256_CBC.block_size()]; let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()];
let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap(); let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap();
let rest = cr.finalize(&mut unciphered_data[count..]).unwrap(); let rest = cr.finalize(&mut unciphered_data[count..]).unwrap();
unciphered_data.truncate(count + rest); unciphered_data.truncate(count + rest);
@ -341,7 +404,7 @@ mod tests {
assert_eq!(&unciphered_data, expected_unciphered_data); assert_eq!(&unciphered_data, expected_unciphered_data);
} }
fn cipher_test(ciphertype: super::Type, pt: &str, ct: &str, key: &str, iv: &str) { fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) {
use serialize::hex::ToHex; use serialize::hex::ToHex;
let pt = pt.from_hex().unwrap(); let pt = pt.from_hex().unwrap();
@ -372,7 +435,7 @@ mod tests {
let key = "97CD440324DA5FD1F7955C1C13B6B466"; let key = "97CD440324DA5FD1F7955C1C13B6B466";
let iv = ""; let iv = "";
cipher_test(super::Type::RC4_128, pt, ct, key, iv); cipher_test(super::Cipher::rc4(), pt, ct, key, iv);
} }
#[test] #[test]
@ -387,7 +450,7 @@ mod tests {
4180026ad640b74243b3133e7b9fae629403f6733423dae28"; 4180026ad640b74243b3133e7b9fae629403f6733423dae28";
let iv = "db200efb7eaaa737dbdf40babb68953f"; let iv = "db200efb7eaaa737dbdf40babb68953f";
cipher_test(super::Type::AES_256_XTS, pt, ct, key, iv); cipher_test(super::Cipher::aes_256_xts(), pt, ct, key, iv);
} }
#[test] #[test]
@ -400,7 +463,7 @@ mod tests {
let key = "2B7E151628AED2A6ABF7158809CF4F3C"; let key = "2B7E151628AED2A6ABF7158809CF4F3C";
let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"; let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
cipher_test(super::Type::AES_128_CTR, pt, ct, key, iv); cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv);
} }
#[test] #[test]
@ -412,7 +475,7 @@ mod tests {
let key = "2b7e151628aed2a6abf7158809cf4f3c"; let key = "2b7e151628aed2a6abf7158809cf4f3c";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_128_CFB1, pt, ct, key, iv); cipher_test(super::Cipher::aes_128_cfb1(), pt, ct, key, iv);
} }
#[test] #[test]
@ -423,7 +486,7 @@ mod tests {
let key = "2b7e151628aed2a6abf7158809cf4f3c"; let key = "2b7e151628aed2a6abf7158809cf4f3c";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_128_CFB128, pt, ct, key, iv); cipher_test(super::Cipher::aes_128_cfb128(), pt, ct, key, iv);
} }
#[test] #[test]
@ -434,7 +497,7 @@ mod tests {
let key = "2b7e151628aed2a6abf7158809cf4f3c"; let key = "2b7e151628aed2a6abf7158809cf4f3c";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_128_CFB8, pt, ct, key, iv); cipher_test(super::Cipher::aes_128_cfb8(), pt, ct, key, iv);
} }
#[test] #[test]
@ -445,7 +508,7 @@ mod tests {
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_256_CFB1, pt, ct, key, iv); cipher_test(super::Cipher::aes_256_cfb1(), pt, ct, key, iv);
} }
#[test] #[test]
@ -456,7 +519,7 @@ mod tests {
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_256_CFB128, pt, ct, key, iv); cipher_test(super::Cipher::aes_256_cfb128(), pt, ct, key, iv);
} }
#[test] #[test]
@ -467,7 +530,7 @@ mod tests {
let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
let iv = "000102030405060708090a0b0c0d0e0f"; let iv = "000102030405060708090a0b0c0d0e0f";
cipher_test(super::Type::AES_256_CFB8, pt, ct, key, iv); cipher_test(super::Cipher::aes_256_cfb8(), pt, ct, key, iv);
} }
#[test] #[test]
@ -478,7 +541,7 @@ mod tests {
let key = "7cb66337f3d3c0fe"; let key = "7cb66337f3d3c0fe";
let iv = "0001020304050607"; let iv = "0001020304050607";
cipher_test(super::Type::DES_CBC, pt, ct, key, iv); cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv);
} }
#[test] #[test]
@ -489,6 +552,6 @@ mod tests {
let key = "7cb66337f3d3c0fe"; let key = "7cb66337f3d3c0fe";
let iv = "0001020304050607"; let iv = "0001020304050607";
cipher_test(super::Type::DES_ECB, pt, ct, key, iv); cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv);
} }
} }

View File

@ -88,13 +88,12 @@ mod compat {
mod tests { mod tests {
use super::DH; use super::DH;
use bn::BigNum; use bn::BigNum;
use ssl::SslContext; use ssl::{SslMethod, SslContext};
use ssl::SslMethod::Tls;
#[test] #[test]
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_dh_rfc5114() { fn test_dh_rfc5114() {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
let dh1 = DH::get_1024_160().unwrap(); let dh1 = DH::get_1024_160().unwrap();
ctx.set_tmp_dh(&dh1).unwrap(); ctx.set_tmp_dh(&dh1).unwrap();
let dh2 = DH::get_2048_224().unwrap(); let dh2 = DH::get_2048_224().unwrap();
@ -105,7 +104,7 @@ mod tests {
#[test] #[test]
fn test_dh() { fn test_dh() {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\ let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\ E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\ 6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
@ -135,7 +134,7 @@ mod tests {
#[test] #[test]
fn test_dh_from_pem() { fn test_dh_from_pem() {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
let params = include_bytes!("../../test/dhparams.pem"); let params = include_bytes!("../../test/dhparams.pem");
let dh = DH::from_pem(params).ok().expect("Failed to load PEM"); let dh = DH::from_pem(params).ok().expect("Failed to load PEM");
ctx.set_tmp_dh(&dh).unwrap(); ctx.set_tmp_dh(&dh).unwrap();

View File

@ -16,8 +16,6 @@ extern crate tempdir;
#[doc(inline)] #[doc(inline)]
pub use ffi::init; pub use ffi::init;
use nid::Nid;
mod macros; mod macros;
pub mod asn1; pub mod asn1;
@ -30,8 +28,3 @@ pub mod nid;
pub mod ssl; pub mod ssl;
pub mod version; pub mod version;
pub mod x509; pub mod x509;
trait HashTypeInternals {
fn as_nid(&self) -> Nid;
fn evp_md(&self) -> *const ffi::EVP_MD;
}

View File

@ -76,13 +76,29 @@ bitflags! {
} }
} }
/// Determines the SSL method supported #[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct SslMethod(*const ffi::SSL_METHOD);
pub enum SslMethod {
/// Support the TLS protocol impl SslMethod {
Tls, /// Support all versions of the TLS protocol.
/// Support DTLS protocol ///
Dtls, /// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method`
/// on OpenSSL 1.0.x.
pub fn tls() -> SslMethod {
SslMethod(compat::tls_method())
}
/// Support all versions of the DTLS protocol.
///
/// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method`
/// on OpenSSL 1.0.x.
pub fn dtls() -> SslMethod {
SslMethod(compat::dtls_method())
}
pub fn as_ptr(&self) -> *const ffi::SSL_METHOD {
self.0
}
} }
/// Determines the type of certificate verification used /// Determines the type of certificate verification used
@ -391,9 +407,9 @@ impl<'a> SslContextRef<'a> {
} }
} }
pub fn set_read_ahead(&mut self, m: u32) { pub fn set_read_ahead(&mut self, read_ahead: bool) {
unsafe { unsafe {
ffi::SSL_CTX_set_read_ahead(self.as_ptr(), m as c_long); ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as c_long);
} }
} }
@ -653,15 +669,10 @@ impl SslContext {
init(); init();
let mut ctx = unsafe { let mut ctx = unsafe {
let method = compat::get_method(method); let ctx = try_ssl_null!(ffi::SSL_CTX_new(method.as_ptr()));
let ctx = try_ssl_null!(ffi::SSL_CTX_new(method));
SslContext::from_ptr(ctx) SslContext::from_ptr(ctx)
}; };
match method {
SslMethod::Dtls => ctx.set_read_ahead(1),
_ => {}
}
// this is a bit dubious (?) // this is a bit dubious (?)
try!(ctx.set_mode(ffi::SSL_MODE_AUTO_RETRY | ffi::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)); try!(ctx.set_mode(ffi::SSL_MODE_AUTO_RETRY | ffi::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER));
@ -1374,8 +1385,6 @@ mod compat {
pub use ffi::{SSL_CTX_get_options, SSL_CTX_set_options}; pub use ffi::{SSL_CTX_get_options, SSL_CTX_set_options};
pub use ffi::{SSL_CTX_clear_options, SSL_CTX_up_ref}; pub use ffi::{SSL_CTX_clear_options, SSL_CTX_up_ref};
use super::SslMethod;
pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int {
ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL_CTX, ffi::CRYPTO_get_ex_new_index(ffi::CRYPTO_EX_INDEX_SSL_CTX,
0, 0,
@ -1394,10 +1403,15 @@ mod compat {
Some(f)) Some(f))
} }
pub unsafe fn get_method(method: SslMethod) -> *const ffi::SSL_METHOD { pub fn tls_method() -> *const ffi::SSL_METHOD {
match method { unsafe {
SslMethod::Tls => ffi::TLS_method(), ffi::TLS_method()
SslMethod::Dtls => ffi::DTLS_method(), }
}
pub fn dtls_method() -> *const ffi::SSL_METHOD {
unsafe {
ffi::DTLS_method()
} }
} }
} }
@ -1410,8 +1424,6 @@ mod compat {
use ffi; use ffi;
use libc::{self, c_long, c_ulong, c_int}; use libc::{self, c_long, c_ulong, c_int};
use super::SslMethod;
pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong { pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong {
ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTX_ctrl(ctx as *mut _,
ffi::SSL_CTRL_OPTIONS, ffi::SSL_CTRL_OPTIONS,
@ -1451,13 +1463,6 @@ mod compat {
Some(f)) Some(f))
} }
pub unsafe fn get_method(method: SslMethod) -> *const ffi::SSL_METHOD {
match method {
SslMethod::Tls => ffi::SSLv23_method(),
SslMethod::Dtls => ffi::DTLSv1_method(),
}
}
pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int { pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int {
ffi::CRYPTO_add_lock(&mut (*ssl).references, ffi::CRYPTO_add_lock(&mut (*ssl).references,
1, 1,
@ -1466,4 +1471,16 @@ mod compat {
line!() as libc::c_int); line!() as libc::c_int);
0 0
} }
pub fn tls_method() -> *const ffi::SSL_METHOD {
unsafe {
ffi::SSLv23_method()
}
}
pub fn dtls_method() -> *const ffi::SSL_METHOD {
unsafe {
ffi::DTLSv1_method()
}
}
} }

View File

@ -14,10 +14,9 @@ use std::time::Duration;
use tempdir::TempDir; use tempdir::TempDir;
use crypto::hash::Type::SHA256; use crypto::hash::MessageDigest;
use ssl; use ssl;
use ssl::SSL_VERIFY_PEER; use ssl::SSL_VERIFY_PEER;
use ssl::SslMethod::Tls;
use ssl::{SslMethod, HandshakeError}; use ssl::{SslMethod, HandshakeError};
use ssl::error::Error; use ssl::error::Error;
use ssl::{SslContext, SslStream}; use ssl::{SslContext, SslStream};
@ -31,7 +30,6 @@ use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
use crypto::pkey::PKey; use crypto::pkey::PKey;
use std::net::UdpSocket; use std::net::UdpSocket;
use ssl::SslMethod::Dtls;
mod select; mod select;
@ -171,7 +169,7 @@ macro_rules! run_test(
use ssl::SslMethod; use ssl::SslMethod;
use ssl::{SslContext, Ssl, SslStream}; use ssl::{SslContext, Ssl, SslStream};
use ssl::SSL_VERIFY_PEER; use ssl::SSL_VERIFY_PEER;
use crypto::hash::Type::{SHA1, SHA256}; use crypto::hash::MessageDigest;
use x509::X509StoreContext; use x509::X509StoreContext;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use super::Server; use super::Server;
@ -179,14 +177,14 @@ macro_rules! run_test(
#[test] #[test]
fn sslv23() { fn sslv23() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
$blk(SslMethod::Tls, stream); $blk(SslMethod::tls(), stream);
} }
#[test] #[test]
#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467) #[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn dtlsv1() { fn dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(Some("hello")); let (_s, stream) = Server::new_dtlsv1(Some("hello"));
$blk(SslMethod::Dtls, stream); $blk(SslMethod::dtls(), stream);
} }
} }
); );
@ -314,7 +312,7 @@ run_test!(verify_callback_data, |method, stream| {
match cert { match cert {
None => false, None => false,
Some(cert) => { Some(cert) => {
let fingerprint = cert.fingerprint(SHA1).unwrap(); let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
fingerprint == node_id fingerprint == node_id
} }
} }
@ -343,7 +341,7 @@ run_test!(ssl_verify_callback, |method, stream| {
match x509.current_cert() { match x509.current_cert() {
None => false, None => false,
Some(cert) => { Some(cert) => {
let fingerprint = cert.fingerprint(SHA1).unwrap(); let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
fingerprint == node_id fingerprint == node_id
} }
} }
@ -364,7 +362,7 @@ fn test_write_hits_stream() {
let addr = listener.local_addr().unwrap(); let addr = listener.local_addr().unwrap();
let guard = thread::spawn(move || { let guard = thread::spawn(move || {
let ctx = SslContext::new(Tls).unwrap(); let ctx = SslContext::new(SslMethod::tls()).unwrap();
let stream = TcpStream::connect(addr).unwrap(); let stream = TcpStream::connect(addr).unwrap();
let mut stream = SslStream::connect(&ctx, stream).unwrap(); let mut stream = SslStream::connect(&ctx, stream).unwrap();
@ -372,7 +370,7 @@ fn test_write_hits_stream() {
stream stream
}); });
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM).unwrap(); ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM).unwrap();
ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM).unwrap(); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM).unwrap();
@ -392,7 +390,7 @@ fn test_set_certificate_and_private_key() {
let cert = include_bytes!("../../../test/cert.pem"); let cert = include_bytes!("../../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap(); let cert = X509::from_pem(cert).unwrap();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_private_key(&key).unwrap(); ctx.set_private_key(&key).unwrap();
ctx.set_certificate(&cert).unwrap(); ctx.set_certificate(&cert).unwrap();
@ -420,7 +418,7 @@ run_test!(clear_ctx_options, |method, _| {
#[test] #[test]
fn test_write() { fn test_write() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), stream).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), stream).unwrap();
stream.write_all("hello".as_bytes()).unwrap(); stream.write_all("hello".as_bytes()).unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
stream.write_all(" there".as_bytes()).unwrap(); stream.write_all(" there".as_bytes()).unwrap();
@ -430,7 +428,7 @@ fn test_write() {
#[test] #[test]
fn test_write_direct() { fn test_write_direct() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), stream).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), stream).unwrap();
stream.write_all("hello".as_bytes()).unwrap(); stream.write_all("hello".as_bytes()).unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
stream.write_all(" there".as_bytes()).unwrap(); stream.write_all(" there".as_bytes()).unwrap();
@ -440,7 +438,7 @@ fn test_write_direct() {
run_test!(get_peer_certificate, |method, stream| { run_test!(get_peer_certificate, |method, stream| {
let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap(); let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
let cert = stream.ssl().peer_certificate().unwrap(); let cert = stream.ssl().peer_certificate().unwrap();
let fingerprint = cert.fingerprint(SHA1).unwrap(); let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let node_id = node_hash_str.from_hex().unwrap(); let node_id = node_hash_str.from_hex().unwrap();
assert_eq!(node_id, fingerprint) assert_eq!(node_id, fingerprint)
@ -451,7 +449,7 @@ run_test!(get_peer_certificate, |method, stream| {
fn test_write_dtlsv1() { fn test_write_dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(iter::repeat("y\n")); let (_s, stream) = Server::new_dtlsv1(iter::repeat("y\n"));
let mut stream = SslStream::connect(&SslContext::new(Dtls).unwrap(), stream).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::dtls()).unwrap(), stream).unwrap();
stream.write_all(b"hello").unwrap(); stream.write_all(b"hello").unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
stream.write_all(b" there").unwrap(); stream.write_all(b" there").unwrap();
@ -461,7 +459,7 @@ fn test_write_dtlsv1() {
#[test] #[test]
fn test_read() { fn test_read() {
let (_s, tcp) = Server::new(); let (_s, tcp) = Server::new();
let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error"); io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
@ -470,7 +468,7 @@ fn test_read() {
#[test] #[test]
fn test_read_direct() { fn test_read_direct() {
let (_s, tcp) = Server::new(); let (_s, tcp) = Server::new();
let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
io::copy(&mut stream, &mut io::sink()).ok().expect("read error"); io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
@ -479,7 +477,7 @@ fn test_read_direct() {
#[test] #[test]
fn test_pending() { fn test_pending() {
let (_s, tcp) = Server::new(); let (_s, tcp) = Server::new();
let mut stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), tcp).unwrap();
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
stream.flush().unwrap(); stream.flush().unwrap();
@ -502,7 +500,7 @@ fn test_pending() {
#[test] #[test]
fn test_state() { fn test_state() {
let (_s, tcp) = Server::new(); let (_s, tcp) = Server::new();
let stream = SslStream::connect(&SslContext::new(Tls).unwrap(), tcp).unwrap(); let stream = SslStream::connect(&SslContext::new(SslMethod::tls()).unwrap(), tcp).unwrap();
assert_eq!(stream.ssl().state_string(), "SSLOK "); assert_eq!(stream.ssl().state_string(), "SSLOK ");
assert_eq!(stream.ssl().state_string_long(), assert_eq!(stream.ssl().state_string_long(),
"SSL negotiation finished successfully"); "SSL negotiation finished successfully");
@ -514,7 +512,7 @@ fn test_state() {
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_connect_with_unilateral_alpn() { fn test_connect_with_unilateral_alpn() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -535,7 +533,7 @@ fn test_connect_with_unilateral_alpn() {
#[test] #[test]
fn test_connect_with_unilateral_npn() { fn test_connect_with_unilateral_npn() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -557,7 +555,7 @@ fn test_connect_with_unilateral_npn() {
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_connect_with_alpn_successful_multiple_matching() { fn test_connect_with_alpn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn(); let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -579,7 +577,7 @@ fn test_connect_with_alpn_successful_multiple_matching() {
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_connect_with_npn_successful_multiple_matching() { fn test_connect_with_npn_successful_multiple_matching() {
let (_s, stream) = Server::new_alpn(); let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -602,7 +600,7 @@ fn test_connect_with_npn_successful_multiple_matching() {
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_connect_with_alpn_successful_single_match() { fn test_connect_with_alpn_successful_single_match() {
let (_s, stream) = Server::new_alpn(); let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -626,7 +624,7 @@ fn test_connect_with_alpn_successful_single_match() {
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn test_connect_with_npn_successful_single_match() { fn test_connect_with_npn_successful_single_match() {
let (_s, stream) = Server::new_alpn(); let (_s, stream) = Server::new_alpn();
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -650,7 +648,7 @@ fn test_npn_server_advertise_multiple() {
let localhost = listener.local_addr().unwrap(); let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server... // We create a different context instance for the server...
let listener_ctx = { let listener_ctx = {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@ -665,7 +663,7 @@ fn test_npn_server_advertise_multiple() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap(); let _ = SslStream::accept(&listener_ctx, stream).unwrap();
}); });
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -691,7 +689,7 @@ fn test_alpn_server_advertise_multiple() {
let localhost = listener.local_addr().unwrap(); let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server... // We create a different context instance for the server...
let listener_ctx = { let listener_ctx = {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@ -706,7 +704,7 @@ fn test_alpn_server_advertise_multiple() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap(); let _ = SslStream::accept(&listener_ctx, stream).unwrap();
}); });
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]);
match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { match ctx.set_CA_file(&Path::new("test/root-ca.pem")) {
@ -732,7 +730,7 @@ fn test_alpn_server_select_none() {
let localhost = listener.local_addr().unwrap(); let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server... // We create a different context instance for the server...
let listener_ctx = { let listener_ctx = {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@ -747,7 +745,7 @@ fn test_alpn_server_select_none() {
let _ = SslStream::accept(&listener_ctx, stream).unwrap(); let _ = SslStream::accept(&listener_ctx, stream).unwrap();
}); });
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]);
ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap();
@ -767,7 +765,7 @@ fn test_alpn_server_select_none() {
let localhost = listener.local_addr().unwrap(); let localhost = listener.local_addr().unwrap();
// We create a different context instance for the server... // We create a different context instance for the server...
let listener_ctx = { let listener_ctx = {
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
@ -782,7 +780,7 @@ fn test_alpn_server_select_none() {
assert!(SslStream::accept(&listener_ctx, stream).is_err()); assert!(SslStream::accept(&listener_ctx, stream).is_err());
}); });
let mut ctx = SslContext::new(Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]);
ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap();
@ -797,18 +795,15 @@ mod dtlsv1 {
use std::net::TcpStream; use std::net::TcpStream;
use std::thread; use std::thread;
use crypto::hash::Type::SHA256; use crypto::hash::MessageDigest;
use ssl::SslMethod; use ssl::SslMethod;
use ssl::SslMethod::Dtls;
use ssl::{SslContext, SslStream}; use ssl::{SslContext, SslStream};
use ssl::SSL_VERIFY_PEER; use ssl::SSL_VERIFY_PEER;
use x509::X509StoreContext; use x509::X509StoreContext;
const PROTOCOL: SslMethod = Dtls;
#[test] #[test]
fn test_new_ctx() { fn test_new_ctx() {
SslContext::new(PROTOCOL).unwrap(); SslContext::new(SslMethod::dtls()).unwrap();
} }
} }
@ -817,7 +812,7 @@ mod dtlsv1 {
fn test_read_dtlsv1() { fn test_read_dtlsv1() {
let (_s, stream) = Server::new_dtlsv1(Some("hello")); let (_s, stream) = Server::new_dtlsv1(Some("hello"));
let mut stream = SslStream::connect(&SslContext::new(Dtls).unwrap(), stream).unwrap(); let mut stream = SslStream::connect(&SslContext::new(SslMethod::dtls()).unwrap(), stream).unwrap();
let mut buf = [0u8; 100]; let mut buf = [0u8; 100];
assert!(stream.read(&mut buf).is_ok()); assert!(stream.read(&mut buf).is_ok());
} }
@ -857,7 +852,7 @@ fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>)
fn test_write_nonblocking() { fn test_write_nonblocking() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap(); stream.set_nonblocking(true).unwrap();
let cx = SslContext::new(Tls).unwrap(); let cx = SslContext::new(SslMethod::tls()).unwrap();
let mut stream = handshake(SslStream::connect(&cx, stream)); let mut stream = handshake(SslStream::connect(&cx, stream));
let mut iterations = 0; let mut iterations = 0;
@ -895,7 +890,7 @@ fn test_write_nonblocking() {
fn test_read_nonblocking() { fn test_read_nonblocking() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
stream.set_nonblocking(true).unwrap(); stream.set_nonblocking(true).unwrap();
let cx = SslContext::new(Tls).unwrap(); let cx = SslContext::new(SslMethod::tls()).unwrap();
let mut stream = handshake(SslStream::connect(&cx, stream)); let mut stream = handshake(SslStream::connect(&cx, stream));
let mut iterations = 0; let mut iterations = 0;
@ -969,7 +964,7 @@ fn write_panic() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let stream = ExplodingStream(stream); let stream = ExplodingStream(stream);
let ctx = SslContext::new(SslMethod::Tls).unwrap(); let ctx = SslContext::new(SslMethod::tls()).unwrap();
let _ = SslStream::connect(&ctx, stream); let _ = SslStream::connect(&ctx, stream);
} }
@ -997,7 +992,7 @@ fn read_panic() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let stream = ExplodingStream(stream); let stream = ExplodingStream(stream);
let ctx = SslContext::new(SslMethod::Tls).unwrap(); let ctx = SslContext::new(SslMethod::tls()).unwrap();
let _ = SslStream::connect(&ctx, stream); let _ = SslStream::connect(&ctx, stream);
} }
@ -1025,7 +1020,7 @@ fn flush_panic() {
let (_s, stream) = Server::new(); let (_s, stream) = Server::new();
let stream = ExplodingStream(stream); let stream = ExplodingStream(stream);
let ctx = SslContext::new(SslMethod::Tls).unwrap(); let ctx = SslContext::new(SslMethod::tls()).unwrap();
let mut stream = SslStream::connect(&ctx, stream).ok().unwrap(); let mut stream = SslStream::connect(&ctx, stream).ok().unwrap();
let _ = stream.flush(); let _ = stream.flush();
} }
@ -1033,12 +1028,12 @@ fn flush_panic() {
#[test] #[test]
fn refcount_ssl_context() { fn refcount_ssl_context() {
let mut ssl = { let mut ssl = {
let ctx = SslContext::new(SslMethod::Tls).unwrap(); let ctx = SslContext::new(SslMethod::tls()).unwrap();
ssl::Ssl::new(&ctx).unwrap() ssl::Ssl::new(&ctx).unwrap()
}; };
{ {
let new_ctx_a = SslContext::new(SslMethod::Tls).unwrap(); let new_ctx_a = SslContext::new(SslMethod::tls()).unwrap();
let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a); let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a);
} }
} }
@ -1046,7 +1041,7 @@ fn refcount_ssl_context() {
#[test] #[test]
#[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :(
fn default_verify_paths() { fn default_verify_paths() {
let mut ctx = SslContext::new(SslMethod::Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_default_verify_paths().unwrap(); ctx.set_default_verify_paths().unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
let s = TcpStream::connect("google.com:443").unwrap(); let s = TcpStream::connect("google.com:443").unwrap();
@ -1065,7 +1060,7 @@ fn default_verify_paths() {
fn add_extra_chain_cert() { fn add_extra_chain_cert() {
let cert = include_bytes!("../../../test/cert.pem"); let cert = include_bytes!("../../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap(); let cert = X509::from_pem(cert).unwrap();
let mut ctx = SslContext::new(SslMethod::Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.add_extra_chain_cert(&cert).unwrap(); ctx.add_extra_chain_cert(&cert).unwrap();
} }
@ -1073,7 +1068,7 @@ fn add_extra_chain_cert() {
#[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :(
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn valid_hostname() { fn valid_hostname() {
let mut ctx = SslContext::new(SslMethod::Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_default_verify_paths().unwrap(); ctx.set_default_verify_paths().unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);
@ -1097,7 +1092,7 @@ fn valid_hostname() {
#[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :(
#[cfg(feature = "openssl-102")] #[cfg(feature = "openssl-102")]
fn invalid_hostname() { fn invalid_hostname() {
let mut ctx = SslContext::new(SslMethod::Tls).unwrap(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap();
ctx.set_default_verify_paths().unwrap(); ctx.set_default_verify_paths().unwrap();
ctx.set_verify(SSL_VERIFY_PEER); ctx.set_verify(SSL_VERIFY_PEER);

View File

@ -10,13 +10,10 @@ use std::slice;
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
use HashTypeInternals;
use asn1::Asn1Time; use asn1::Asn1Time;
use asn1::Asn1TimeRef; use asn1::Asn1TimeRef;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use crypto::hash; use crypto::hash::MessageDigest;
use crypto::hash::Type as HashType;
use crypto::pkey::PKey; use crypto::pkey::PKey;
use crypto::rand::rand_bytes; use crypto::rand::rand_bytes;
use ffi; use ffi;
@ -129,7 +126,7 @@ impl X509StoreContext {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use openssl::crypto::hash::Type; /// use openssl::crypto::hash::MessageDigest;
/// use openssl::crypto::pkey::PKey; /// use openssl::crypto::pkey::PKey;
/// use openssl::crypto::rsa::RSA; /// use openssl::crypto::rsa::RSA;
/// use openssl::x509::X509Generator; /// use openssl::x509::X509Generator;
@ -141,7 +138,7 @@ impl X509StoreContext {
/// let gen = X509Generator::new() /// let gen = X509Generator::new()
/// .set_valid_period(365*2) /// .set_valid_period(365*2)
/// .add_name("CN".to_owned(), "SuperMegaCorp Inc.".to_owned()) /// .add_name("CN".to_owned(), "SuperMegaCorp Inc.".to_owned())
/// .set_sign_hash(Type::SHA256) /// .set_sign_hash(MessageDigest::sha256())
/// .add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature])); /// .add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature]));
/// ///
/// let cert = gen.sign(&pkey).unwrap(); /// let cert = gen.sign(&pkey).unwrap();
@ -152,7 +149,7 @@ pub struct X509Generator {
days: u32, days: u32,
names: Vec<(String, String)>, names: Vec<(String, String)>,
extensions: Extensions, extensions: Extensions,
hash_type: HashType, hash_type: MessageDigest,
} }
impl X509Generator { impl X509Generator {
@ -168,7 +165,7 @@ impl X509Generator {
days: 365, days: 365,
names: vec![], names: vec![],
extensions: Extensions::new(), extensions: Extensions::new(),
hash_type: HashType::SHA1, hash_type: MessageDigest::sha1(),
} }
} }
@ -239,7 +236,7 @@ impl X509Generator {
self self
} }
pub fn set_sign_hash(mut self, hash_type: hash::Type) -> X509Generator { pub fn set_sign_hash(mut self, hash_type: MessageDigest) -> X509Generator {
self.hash_type = hash_type; self.hash_type = hash_type;
self self
} }
@ -358,7 +355,7 @@ impl X509Generator {
&ext.to_string())); &ext.to_string()));
} }
let hash_fn = self.hash_type.evp_md(); let hash_fn = self.hash_type.as_ptr();
try_ssl!(ffi::X509_sign(x509.as_ptr(), p_key.as_ptr(), hash_fn)); try_ssl!(ffi::X509_sign(x509.as_ptr(), p_key.as_ptr(), hash_fn));
Ok(x509) Ok(x509)
} }
@ -380,7 +377,7 @@ impl X509Generator {
try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _)); try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _));
} }
let hash_fn = self.hash_type.evp_md(); let hash_fn = self.hash_type.as_ptr();
try_ssl!(ffi::X509_REQ_sign(req, p_key.as_ptr(), hash_fn)); try_ssl!(ffi::X509_REQ_sign(req, p_key.as_ptr(), hash_fn));
Ok(X509Req::new(req)) Ok(X509Req::new(req))
@ -438,9 +435,9 @@ impl<'a> X509Ref<'a> {
} }
/// Returns certificate fingerprint calculated using provided hash /// Returns certificate fingerprint calculated using provided hash
pub fn fingerprint(&self, hash_type: hash::Type) -> Result<Vec<u8>, ErrorStack> { pub fn fingerprint(&self, hash_type: MessageDigest) -> Result<Vec<u8>, ErrorStack> {
unsafe { unsafe {
let evp = hash_type.evp_md(); let evp = hash_type.as_ptr();
let mut len = ffi::EVP_MAX_MD_SIZE; let mut len = ffi::EVP_MAX_MD_SIZE;
let mut buf = vec![0u8; len as usize]; let mut buf = vec![0u8; len as usize];
try_ssl!(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len)); try_ssl!(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len));

View File

@ -1,6 +1,6 @@
use serialize::hex::FromHex; use serialize::hex::FromHex;
use crypto::hash::Type::SHA1; use crypto::hash::MessageDigest;
use crypto::pkey::PKey; use crypto::pkey::PKey;
use crypto::rsa::RSA; use crypto::rsa::RSA;
use x509::{X509, X509Generator}; use x509::{X509, X509Generator};
@ -14,7 +14,7 @@ fn get_generator() -> X509Generator {
X509Generator::new() X509Generator::new()
.set_valid_period(365 * 2) .set_valid_period(365 * 2)
.add_name("CN".to_string(), "test_me".to_string()) .add_name("CN".to_string(), "test_me".to_string())
.set_sign_hash(SHA1) .set_sign_hash(MessageDigest::sha1())
.add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment]))
.add_extension(ExtKeyUsage(vec![ClientAuth, .add_extension(ExtKeyUsage(vec![ClientAuth,
ServerAuth, ServerAuth,
@ -83,7 +83,7 @@ fn test_req_gen() {
fn test_cert_loading() { fn test_cert_loading() {
let cert = include_bytes!("../../test/cert.pem"); let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let fingerprint = cert.fingerprint(SHA1).unwrap(); let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap();
let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
let hash_vec = hash_str.from_hex().unwrap(); let hash_vec = hash_str.from_hex().unwrap();