diff options
| author | Steven Fackler <[email protected]> | 2016-10-15 17:03:17 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2016-10-15 17:03:17 -0700 |
| commit | fdb4131064412cdd0542e55cc1187cebb52bcc58 (patch) | |
| tree | 80d538b8002fbc9574a21201a39af4bdff0c1cb9 | |
| parent | Correctly bind BIO_new_mem_buf (diff) | |
| parent | Fix set_read_ahead signature (diff) | |
| download | rust-openssl-fdb4131064412cdd0542e55cc1187cebb52bcc58.tar.xz rust-openssl-fdb4131064412cdd0542e55cc1187cebb52bcc58.zip | |
Merge pull request #475 from sfackler/no-enums
Turn enums into structs
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | openssl-sys/src/lib.rs | 2 | ||||
| -rw-r--r-- | openssl/src/crypto/dsa.rs | 110 | ||||
| -rw-r--r-- | openssl/src/crypto/hash.rs | 112 | ||||
| -rw-r--r-- | openssl/src/crypto/pkcs12.rs | 6 | ||||
| -rw-r--r-- | openssl/src/crypto/pkcs5.rs | 43 | ||||
| -rw-r--r-- | openssl/src/crypto/pkey.rs | 12 | ||||
| -rw-r--r-- | openssl/src/crypto/rsa.rs | 46 | ||||
| -rw-r--r-- | openssl/src/crypto/sign.rs | 94 | ||||
| -rw-r--r-- | openssl/src/crypto/symm.rs | 199 | ||||
| -rw-r--r-- | openssl/src/dh/mod.rs | 9 | ||||
| -rw-r--r-- | openssl/src/lib.rs | 7 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 77 | ||||
| -rw-r--r-- | openssl/src/ssl/tests/mod.rs | 95 | ||||
| -rw-r--r-- | openssl/src/x509/mod.rs | 23 | ||||
| -rw-r--r-- | openssl/src/x509/tests.rs | 6 |
16 files changed, 439 insertions, 404 deletions
diff --git a/.travis.yml b/.travis.yml index 347a23c5..55ba716d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ dist: trusty env: global: - TARGET=x86_64-unknown-linux-gnu + - BUILD_OPENSSL_VERSION=1.0.1u matrix: include: # ARM-bit version compat @@ -44,7 +45,6 @@ matrix: - rust: nightly # 64-bit version compat - - env: BUILD_OPENSSL_VERSION=1.0.1u - env: BUILD_OPENSSL_VERSION=1.0.2h - env: BUILD_OPENSSL_VERSION=1.1.0b diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 67b93f25..ae38d1b3 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -110,6 +110,7 @@ pub const CRYPTO_LOCK: c_int = 1; pub const EVP_MAX_MD_SIZE: c_uint = 64; pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; 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_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_ext_key_usage: c_int = 126; pub const NID_key_usage: c_int = 83; +pub const NID_dsa: c_int = 116; pub const NID_hmac: c_int = 855; pub const PKCS5_SALT_LEN: c_int = 8; diff --git a/openssl/src/crypto/dsa.rs b/openssl/src/crypto/dsa.rs index bb4fe474..addaae2f 100644 --- a/openssl/src/crypto/dsa.rs +++ b/openssl/src/crypto/dsa.rs @@ -2,16 +2,14 @@ use ffi; use std::fmt; use error::ErrorStack; 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 bio::{MemBio, MemBioSlice}; -use crypto::hash; -use HashTypeInternals; 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); 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 { self.0 } @@ -282,76 +247,7 @@ mod test { #[test] pub fn test_generate() { - let key = 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!"); - } + DSA::generate(1024).unwrap(); } #[test] diff --git a/openssl/src/crypto/hash.rs b/openssl/src/crypto/hash.rs index e3bf4997..2fa75807 100644 --- a/openssl/src/crypto/hash.rs +++ b/openssl/src/crypto/hash.rs @@ -8,48 +8,57 @@ use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; -use HashTypeInternals; use error::ErrorStack; -use nid::Nid; -/// Message digest (hash) type. #[derive(Copy, Clone)] -pub enum Type { - MD5, - SHA1, - SHA224, - SHA256, - SHA384, - SHA512, - RIPEMD160, -} +pub struct MessageDigest(*const ffi::EVP_MD); -impl HashTypeInternals for Type { - fn as_nid(&self) -> Nid { - 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, +impl MessageDigest { + pub fn md5() -> MessageDigest { + unsafe { + MessageDigest(ffi::EVP_md5()) } } - fn evp_md(&self) -> *const ffi::EVP_MD { + pub fn sha1() -> MessageDigest { unsafe { - match *self { - 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(), - } + 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 + } } #[derive(PartialEq, Copy, Clone)] @@ -68,20 +77,22 @@ use self::State::*; /// 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 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); /// ``` /// /// 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 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[1]).unwrap(); /// let res = h.finish().unwrap(); @@ -96,21 +107,20 @@ use self::State::*; pub struct Hasher { ctx: *mut ffi::EVP_MD_CTX, md: *const ffi::EVP_MD, - type_: Type, + type_: MessageDigest, state: State, } impl Hasher { /// 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(); let ctx = unsafe { try_ssl_null!(EVP_MD_CTX_new()) }; - let md = ty.evp_md(); let mut h = Hasher { ctx: ctx, - md: md, + md: ty.as_ptr(), type_: ty, state: Finalized, }; @@ -204,7 +214,7 @@ impl Drop for Hasher { } /// 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)); try!(h.update(data)); h.finish() @@ -213,10 +223,10 @@ pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> { #[cfg(test)] mod tests { use serialize::hex::{FromHex, ToHex}; - use super::{hash, Hasher, Type}; + use super::{hash, Hasher, MessageDigest}; 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(); assert_eq!(res.to_hex(), hashtest.1); } @@ -259,13 +269,13 @@ mod tests { #[test] fn test_md5() { for test in md5_tests.iter() { - hash_test(Type::MD5, test); + hash_test(MessageDigest::md5(), test); } } #[test] 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() { hash_recycle_test(&mut h, test); } @@ -273,11 +283,11 @@ mod tests { #[test] 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.finish().unwrap(); let res = h.finish().unwrap(); - let null = hash(Type::MD5, &[]).unwrap(); + let null = hash(MessageDigest::md5(), &[]).unwrap(); assert_eq!(res, null); } @@ -287,7 +297,7 @@ mod tests { let inp = md5_tests[i].0.from_hex().unwrap(); assert!(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"); let mut h1 = h0.clone(); @@ -315,7 +325,7 @@ mod tests { let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")]; for test in tests.iter() { - hash_test(Type::SHA1, test); + hash_test(MessageDigest::sha1(), test); } } @@ -325,7 +335,7 @@ mod tests { "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")]; 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")]; for test in tests.iter() { - hash_test(Type::RIPEMD160, test); + hash_test(MessageDigest::ripemd160(), test); } } } diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs index 5f03a3d5..b028f29d 100644 --- a/openssl/src/crypto/pkcs12.rs +++ b/openssl/src/crypto/pkcs12.rs @@ -97,7 +97,7 @@ mod compat { #[cfg(test)] mod test { - use crypto::hash::Type::SHA1; + use crypto::hash::MessageDigest; use serialize::hex::ToHex; use super::*; @@ -108,11 +108,11 @@ mod test { let pkcs12 = Pkcs12::from_der(der).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"); 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"); } } diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs index adcbc9db..9d348b89 100644 --- a/openssl/src/crypto/pkcs5.rs +++ b/openssl/src/crypto/pkcs5.rs @@ -2,9 +2,8 @@ use libc::c_int; use std::ptr; use ffi; -use HashTypeInternals; -use crypto::hash; -use crypto::symm; +use crypto::hash::MessageDigest; +use crypto::symm::Cipher; use error::ErrorStack; #[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 /// another more modern key derivation algorithm. -pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, - message_digest_type: hash::Type, +pub fn evp_bytes_to_key_pbkdf1_compatible(cipher: Cipher, + digest: MessageDigest, data: &[u8], salt: Option<&[u8]>, count: u32) @@ -40,11 +39,11 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type, ffi::init(); - let typ = typ.as_ptr(); - let message_digest_type = message_digest_type.evp_md(); + let cipher = cipher.as_ptr(); + let digest = digest.as_ptr(); - let len = ffi::EVP_BytesToKey(typ, - message_digest_type, + let len = ffi::EVP_BytesToKey(cipher, + digest, salt_ptr, data.as_ptr(), 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 iv = vec![0; len as usize]; - try_ssl!(ffi::EVP_BytesToKey(typ, - message_digest_type, + try_ssl!(ffi::EVP_BytesToKey(cipher, + digest, salt_ptr, data.as_ptr(), data.len() as c_int, @@ -97,7 +96,7 @@ pub fn pbkdf2_hmac_sha1(pass: &[u8], pub fn pbkdf2_hmac(pass: &[u8], salt: &[u8], iter: usize, - hash: hash::Type, + hash: MessageDigest, keylen: usize) -> Result<Vec<u8>, ErrorStack> { unsafe { @@ -108,7 +107,7 @@ pub fn pbkdf2_hmac(pass: &[u8], salt.as_ptr(), salt.len() as c_int, iter as c_int, - hash.evp_md(), + hash.as_ptr(), keylen as c_int, out.as_mut_ptr())); Ok(out) @@ -117,8 +116,8 @@ pub fn pbkdf2_hmac(pass: &[u8], #[cfg(test)] mod tests { - use crypto::hash; - use crypto::symm; + use crypto::hash::MessageDigest; + use crypto::symm::Cipher; // Test vectors from // 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 #[test] 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, 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, 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 #[test] 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, 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, @@ -185,7 +184,7 @@ mod tests { 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]); - 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, 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, @@ -198,7 +197,7 @@ mod tests { assert_eq!(super::pbkdf2_hmac(b"passwordPASSWORDpassword", b"salt\0\0\0", 50, - hash::Type::SHA512, + MessageDigest::sha512(), 64).unwrap(), 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, @@ -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]; - assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(symm::Type::AES_256_CBC, - hash::Type::SHA1, + assert_eq!(super::evp_bytes_to_key_pbkdf1_compatible(Cipher::aes_256_cbc(), + MessageDigest::sha1(), &data, Some(&salt), 1).unwrap(), diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs index 8b408d29..67ff7520 100644 --- a/openssl/src/crypto/pkey.rs +++ b/openssl/src/crypto/pkey.rs @@ -4,6 +4,7 @@ use std::mem; use ffi; use bio::{MemBio, MemBioSlice}; +use crypto::dsa::DSA; use crypto::rsa::RSA; use error::ErrorStack; 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. pub fn hmac(key: &[u8]) -> Result<PKey, ErrorStack> { unsafe { diff --git a/openssl/src/crypto/rsa.rs b/openssl/src/crypto/rsa.rs index eebb9622..1212ee3a 100644 --- a/openssl/src/crypto/rsa.rs +++ b/openssl/src/crypto/rsa.rs @@ -11,19 +11,19 @@ use crypto::util::{CallbackState, invoke_passwd_cb}; /// Type of encryption padding to use. #[derive(Copy, Clone)] -pub enum Padding { - None, - OAEP, - PKCS1v15 -} +pub struct Padding(c_int); impl Padding { - fn openssl_padding_code(&self) -> c_int { - match *self { - Padding::None => ffi::RSA_NO_PADDING, - Padding::OAEP => ffi::RSA_PKCS1_OAEP_PADDING, - Padding::PKCS1v15 => ffi::RSA_PKCS1_PADDING - } + pub fn none() -> Padding { + Padding(ffi::RSA_NO_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(), to.as_mut_ptr(), self.0, - padding.openssl_padding_code())); + padding.0)); to.truncate(enc_len as usize); Ok(to) } @@ -202,7 +202,7 @@ impl RSA { from.as_ptr(), to.as_mut_ptr(), self.0, - padding.openssl_padding_code())); + padding.0)); assert!(enc_len as u32 == k_len); Ok(to) @@ -221,7 +221,7 @@ impl RSA { from.as_ptr(), to.as_mut_ptr(), self.0, - padding.openssl_padding_code())); + padding.0)); to.truncate(enc_len as usize); Ok(to) } @@ -239,7 +239,7 @@ impl RSA { from.as_ptr(), to.as_mut_ptr(), self.0, - padding.openssl_padding_code())); + padding.0)); assert!(enc_len as u32 == k_len); Ok(to) @@ -425,13 +425,13 @@ mod test { let public_key = RSA::public_key_from_pem(key).unwrap(); 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); let pkey = include_bytes!("../../test/rsa.pem"); 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); } @@ -444,8 +444,8 @@ mod test { let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); - let emsg = k0.private_encrypt(&msg, Padding::PKCS1v15).unwrap(); - let dmsg = k1.public_decrypt(&emsg, Padding::PKCS1v15).unwrap(); + let emsg = k0.private_encrypt(&msg, Padding::pkcs1()).unwrap(); + let dmsg = k1.public_decrypt(&emsg, Padding::pkcs1()).unwrap(); assert!(msg == dmsg); } @@ -457,8 +457,8 @@ mod test { let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); - let emsg = k1.public_encrypt(&msg, Padding::OAEP).unwrap(); - let dmsg = k0.private_decrypt(&emsg, Padding::OAEP).unwrap(); + let emsg = k1.public_encrypt(&msg, Padding::pkcs1_oaep()).unwrap(); + let dmsg = k0.private_decrypt(&emsg, Padding::pkcs1_oaep()).unwrap(); assert!(msg == dmsg); } @@ -470,8 +470,8 @@ mod test { let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8); - let emsg = k1.public_encrypt(&msg, super::Padding::PKCS1v15).unwrap(); - let dmsg = k0.private_decrypt(&emsg, super::Padding::PKCS1v15).unwrap(); + let emsg = k1.public_encrypt(&msg, super::Padding::pkcs1()).unwrap(); + let dmsg = k0.private_decrypt(&emsg, super::Padding::pkcs1()).unwrap(); assert!(msg == dmsg); } diff --git a/openssl/src/crypto/sign.rs b/openssl/src/crypto/sign.rs index c5d54597..fdedd4d5 100644 --- a/openssl/src/crypto/sign.rs +++ b/openssl/src/crypto/sign.rs @@ -13,7 +13,7 @@ //! use openssl::crypto::sign::{Signer, Verifier}; //! use openssl::crypto::rsa::RSA; //! use openssl::crypto::pkey::PKey; -//! use openssl::crypto::hash::Type; +//! use openssl::crypto::hash::MessageDigest; //! //! // Generate a keypair //! let keypair = RSA::generate(2048).unwrap(); @@ -23,13 +23,13 @@ //! let data2 = b"hola, mundo!"; //! //! // 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(data2).unwrap(); //! let signature = signer.finish().unwrap(); //! //! // 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(data2).unwrap(); //! assert!(verifier.finish(&signature).unwrap()); @@ -40,7 +40,7 @@ //! ```rust //! use openssl::crypto::sign::Signer; //! use openssl::crypto::pkey::PKey; -//! use openssl::crypto::hash::Type; +//! use openssl::crypto::hash::MessageDigest; //! //! // Create a PKey //! let key = PKey::hmac(b"my secret").unwrap(); @@ -49,7 +49,7 @@ //! let data2 = b"hola, mundo!"; //! //! // 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(data2).unwrap(); //! let hmac = signer.finish().unwrap(); @@ -59,8 +59,7 @@ use std::io::{self, Write}; use std::marker::PhantomData; use std::ptr; -use HashTypeInternals; -use crypto::hash::Type; +use crypto::hash::MessageDigest; use crypto::pkey::PKey; use error::ErrorStack; @@ -80,14 +79,14 @@ impl<'a> Drop for 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 { ffi::init(); let ctx = try_ssl_null!(EVP_MD_CTX_new()); let r = ffi::EVP_DigestSignInit(ctx, ptr::null_mut(), - type_.evp_md(), + type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); if r != 1 { @@ -113,6 +112,8 @@ impl<'a> Signer<'a> { let mut buf = vec![0; len]; try_ssl_if!(ffi::EVP_DigestSignFinal(self.0, buf.as_mut_ptr() as *mut _, &mut len) != 1); + // The advertised length is not always equal to the real length for things like DSA + buf.truncate(len); Ok(buf) } } @@ -140,14 +141,14 @@ impl<'a> Drop for 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 { ffi::init(); let ctx = try_ssl_null!(EVP_MD_CTX_new()); let r = ffi::EVP_DigestVerifyInit(ctx, ptr::null_mut(), - type_.evp_md(), + type_.as_ptr(), ptr::null_mut(), pkey.as_ptr()); if r != 1 { @@ -210,9 +211,10 @@ mod test { use serialize::hex::FromHex; use std::iter; - use crypto::hash::Type; + use crypto::hash::MessageDigest; use crypto::sign::{Signer, Verifier}; use crypto::rsa::RSA; + use crypto::dsa::DSA; use crypto::pkey::PKey; static INPUT: &'static [u8] = @@ -240,12 +242,12 @@ mod test { 112, 223, 200, 163, 42, 70, 149, 67, 208, 25, 238, 251, 71]; #[test] - fn test_sign() { + fn rsa_sign() { let key = include_bytes!("../../test/rsa.pem"); let private_key = RSA::private_key_from_pem(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(); let result = signer.finish().unwrap(); @@ -253,29 +255,79 @@ mod test { } #[test] - fn test_verify_ok() { + fn rsa_verify_ok() { let key = include_bytes!("../../test/rsa.pem"); let private_key = RSA::private_key_from_pem(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(); assert!(verifier.finish(SIGNATURE).unwrap()); } #[test] - fn test_verify_invalid() { + fn rsa_verify_invalid() { let key = include_bytes!("../../test/rsa.pem"); let private_key = RSA::private_key_from_pem(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(b"foobar").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() { let pkey = PKey::hmac(key).unwrap(); let mut signer = Signer::new(ty, &pkey).unwrap(); @@ -312,7 +364,7 @@ mod test { .to_vec(), "6f630fad67cda0ee1fb1f562db3aa53e".from_hex().unwrap())]; - test_hmac(Type::MD5, &tests); + test_hmac(MessageDigest::md5(), &tests); } #[test] @@ -343,6 +395,6 @@ mod test { .to_vec(), "e8e99d0f45237d786d6bbaa7965c7808bbff1a91".from_hex().unwrap())]; - test_hmac(Type::SHA1, &tests); + test_hmac(MessageDigest::sha1(), &tests); } } diff --git a/openssl/src/crypto/symm.rs b/openssl/src/crypto/symm.rs index 37754387..8ac6b7cf 100644 --- a/openssl/src/crypto/symm.rs +++ b/openssl/src/crypto/symm.rs @@ -11,57 +11,120 @@ pub enum Mode { Decrypt, } -#[allow(non_camel_case_types)] #[derive(Copy, Clone)] -pub enum Type { - 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, -} +pub struct Cipher(*const ffi::EVP_CIPHER); -impl Type { - pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER { +impl Cipher { + pub fn aes_128_ecb() -> Cipher { unsafe { - match *self { - 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(), - } + Cipher(ffi::EVP_aes_128_ecb()) + } + } + + 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. pub fn key_len(&self) -> usize { 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. pub fn iv_len(&self) -> Option<usize> { 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 { None } else { @@ -85,7 +148,7 @@ impl Type { /// Stream ciphers such as RC4 have a block size of 1. pub fn block_size(&self) -> usize { 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 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`). - pub fn new(t: Type, mode: Mode, key: &[u8], iv: Option<&[u8]>) -> Result<Crypter, ErrorStack> { + /// IV's length does not match the expected length (see `Cipher::iv_len`). + pub fn new(t: Cipher, mode: Mode, key: &[u8], iv: Option<&[u8]>) -> Result<Crypter, ErrorStack> { ffi::init(); unsafe { @@ -165,7 +228,7 @@ impl Crypter { /// # Panics /// /// 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()`. pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result<usize, ErrorStack> { unsafe { @@ -218,7 +281,7 @@ impl Drop for Crypter { * Encrypts data, using the specified crypter type in encrypt mode with the * specified key and iv; returns the resulting (encrypted) data. */ -pub fn encrypt(t: Type, +pub fn encrypt(t: Cipher, key: &[u8], iv: Option<&[u8]>, data: &[u8]) @@ -230,7 +293,7 @@ pub fn encrypt(t: Type, * Decrypts data, using the specified crypter type in decrypt mode with the * specified key and iv; returns the resulting (decrypted) data. */ -pub fn decrypt(t: Type, +pub fn decrypt(t: Cipher, key: &[u8], iv: Option<&[u8]>, data: &[u8]) @@ -238,7 +301,7 @@ pub fn decrypt(t: Type, cipher(t, Mode::Decrypt, key, iv, data) } -fn cipher(t: Type, +fn cipher(t: Cipher, mode: Mode, key: &[u8], iv: Option<&[u8]>, @@ -292,23 +355,23 @@ mod tests { 0xaau8, 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8]; let c0 = [0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 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, &k0, None).unwrap(); 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 rest = c.finalize(&mut r0[count..]).unwrap(); r0.truncate(count + rest); 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, &k0, None).unwrap(); 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 rest = c.finalize(&mut p1[count..]).unwrap(); 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, 0xd7_u8, 0xea_u8, 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_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, &data, Some(&iv)).unwrap(); 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 rest = cr.finalize(&mut unciphered_data[count..]).unwrap(); unciphered_data.truncate(count + rest); @@ -341,7 +404,7 @@ mod tests { 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; let pt = pt.from_hex().unwrap(); @@ -372,7 +435,7 @@ mod tests { let key = "97CD440324DA5FD1F7955C1C13B6B466"; let iv = ""; - cipher_test(super::Type::RC4_128, pt, ct, key, iv); + cipher_test(super::Cipher::rc4(), pt, ct, key, iv); } #[test] @@ -387,7 +450,7 @@ mod tests { 4180026ad640b74243b3133e7b9fae629403f6733423dae28"; 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] @@ -400,7 +463,7 @@ mod tests { let key = "2B7E151628AED2A6ABF7158809CF4F3C"; 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] @@ -412,7 +475,7 @@ mod tests { let key = "2b7e151628aed2a6abf7158809cf4f3c"; 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] @@ -423,7 +486,7 @@ mod tests { let key = "2b7e151628aed2a6abf7158809cf4f3c"; 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] @@ -434,7 +497,7 @@ mod tests { let key = "2b7e151628aed2a6abf7158809cf4f3c"; 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] @@ -445,7 +508,7 @@ mod tests { let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 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] @@ -456,7 +519,7 @@ mod tests { let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 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] @@ -467,7 +530,7 @@ mod tests { let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; 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] @@ -478,7 +541,7 @@ mod tests { let key = "7cb66337f3d3c0fe"; let iv = "0001020304050607"; - cipher_test(super::Type::DES_CBC, pt, ct, key, iv); + cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv); } #[test] @@ -489,6 +552,6 @@ mod tests { let key = "7cb66337f3d3c0fe"; let iv = "0001020304050607"; - cipher_test(super::Type::DES_ECB, pt, ct, key, iv); + cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv); } } diff --git a/openssl/src/dh/mod.rs b/openssl/src/dh/mod.rs index b716ffe0..83807f39 100644 --- a/openssl/src/dh/mod.rs +++ b/openssl/src/dh/mod.rs @@ -88,13 +88,12 @@ mod compat { mod tests { use super::DH; use bn::BigNum; - use ssl::SslContext; - use ssl::SslMethod::Tls; + use ssl::{SslMethod, SslContext}; #[test] #[cfg(feature = "openssl-102")] 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(); ctx.set_tmp_dh(&dh1).unwrap(); let dh2 = DH::get_2048_224().unwrap(); @@ -105,7 +104,7 @@ mod tests { #[test] 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\ E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\ 6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\ @@ -135,7 +134,7 @@ mod tests { #[test] 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 dh = DH::from_pem(params).ok().expect("Failed to load PEM"); ctx.set_tmp_dh(&dh).unwrap(); diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index aa34753c..62968742 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -16,8 +16,6 @@ extern crate tempdir; #[doc(inline)] pub use ffi::init; -use nid::Nid; - mod macros; pub mod asn1; @@ -30,8 +28,3 @@ pub mod nid; pub mod ssl; pub mod version; pub mod x509; - -trait HashTypeInternals { - fn as_nid(&self) -> Nid; - fn evp_md(&self) -> *const ffi::EVP_MD; -} diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 076ac400..7b4f831b 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -76,13 +76,29 @@ bitflags! { } } -/// Determines the SSL method supported -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -pub enum SslMethod { - /// Support the TLS protocol - Tls, - /// Support DTLS protocol - Dtls, +#[derive(Copy, Clone)] +pub struct SslMethod(*const ffi::SSL_METHOD); + +impl SslMethod { + /// Support all versions of the TLS protocol. + /// + /// 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 @@ -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 { - 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(); let mut ctx = unsafe { - let method = compat::get_method(method); - let ctx = try_ssl_null!(ffi::SSL_CTX_new(method)); + let ctx = try_ssl_null!(ffi::SSL_CTX_new(method.as_ptr())); SslContext::from_ptr(ctx) }; - match method { - SslMethod::Dtls => ctx.set_read_ahead(1), - _ => {} - } // this is a bit dubious (?) 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_clear_options, SSL_CTX_up_ref}; - use super::SslMethod; - 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, 0, @@ -1394,10 +1403,15 @@ mod compat { Some(f)) } - pub unsafe fn get_method(method: SslMethod) -> *const ffi::SSL_METHOD { - match method { - SslMethod::Tls => ffi::TLS_method(), - SslMethod::Dtls => ffi::DTLS_method(), + pub fn tls_method() -> *const ffi::SSL_METHOD { + unsafe { + ffi::TLS_method() + } + } + + pub fn dtls_method() -> *const ffi::SSL_METHOD { + unsafe { + ffi::DTLS_method() } } } @@ -1410,8 +1424,6 @@ mod compat { use ffi; 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 { ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTRL_OPTIONS, @@ -1451,13 +1463,6 @@ mod compat { 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 { ffi::CRYPTO_add_lock(&mut (*ssl).references, 1, @@ -1466,4 +1471,16 @@ mod compat { line!() as libc::c_int); 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() + } + } } diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index ce1ba8ca..ac7505f8 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -14,10 +14,9 @@ use std::time::Duration; use tempdir::TempDir; -use crypto::hash::Type::SHA256; +use crypto::hash::MessageDigest; use ssl; use ssl::SSL_VERIFY_PEER; -use ssl::SslMethod::Tls; use ssl::{SslMethod, HandshakeError}; use ssl::error::Error; use ssl::{SslContext, SslStream}; @@ -31,7 +30,6 @@ use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; use crypto::pkey::PKey; use std::net::UdpSocket; -use ssl::SslMethod::Dtls; mod select; @@ -171,7 +169,7 @@ macro_rules! run_test( use ssl::SslMethod; use ssl::{SslContext, Ssl, SslStream}; use ssl::SSL_VERIFY_PEER; - use crypto::hash::Type::{SHA1, SHA256}; + use crypto::hash::MessageDigest; use x509::X509StoreContext; use serialize::hex::FromHex; use super::Server; @@ -179,14 +177,14 @@ macro_rules! run_test( #[test] fn sslv23() { let (_s, stream) = Server::new(); - $blk(SslMethod::Tls, stream); + $blk(SslMethod::tls(), stream); } #[test] #[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467) fn dtlsv1() { 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 { None => false, Some(cert) => { - let fingerprint = cert.fingerprint(SHA1).unwrap(); + let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap(); fingerprint == node_id } } @@ -343,7 +341,7 @@ run_test!(ssl_verify_callback, |method, stream| { match x509.current_cert() { None => false, Some(cert) => { - let fingerprint = cert.fingerprint(SHA1).unwrap(); + let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap(); fingerprint == node_id } } @@ -364,7 +362,7 @@ fn test_write_hits_stream() { let addr = listener.local_addr().unwrap(); 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 mut stream = SslStream::connect(&ctx, stream).unwrap(); @@ -372,7 +370,7 @@ fn test_write_hits_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_certificate_file(&Path::new("test/cert.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 = 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_certificate(&cert).unwrap(); @@ -420,7 +418,7 @@ run_test!(clear_ctx_options, |method, _| { #[test] fn test_write() { 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.flush().unwrap(); stream.write_all(" there".as_bytes()).unwrap(); @@ -430,7 +428,7 @@ fn test_write() { #[test] fn test_write_direct() { 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.flush().unwrap(); stream.write_all(" there".as_bytes()).unwrap(); @@ -440,7 +438,7 @@ fn test_write_direct() { run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).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_id = node_hash_str.from_hex().unwrap(); assert_eq!(node_id, fingerprint) @@ -451,7 +449,7 @@ run_test!(get_peer_certificate, |method, stream| { fn test_write_dtlsv1() { 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.flush().unwrap(); stream.write_all(b" there").unwrap(); @@ -461,7 +459,7 @@ fn test_write_dtlsv1() { #[test] fn test_read() { 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.flush().unwrap(); io::copy(&mut stream, &mut io::sink()).ok().expect("read error"); @@ -470,7 +468,7 @@ fn test_read() { #[test] fn test_read_direct() { 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.flush().unwrap(); io::copy(&mut stream, &mut io::sink()).ok().expect("read error"); @@ -479,7 +477,7 @@ fn test_read_direct() { #[test] fn test_pending() { 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.flush().unwrap(); @@ -502,7 +500,7 @@ fn test_pending() { #[test] fn test_state() { 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_long(), "SSL negotiation finished successfully"); @@ -514,7 +512,7 @@ fn test_state() { #[cfg(feature = "openssl-102")] fn test_connect_with_unilateral_alpn() { 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_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { @@ -535,7 +533,7 @@ fn test_connect_with_unilateral_alpn() { #[test] fn test_connect_with_unilateral_npn() { 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_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); 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")] fn test_connect_with_alpn_successful_multiple_matching() { 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_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); 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")] fn test_connect_with_npn_successful_multiple_matching() { 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_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); 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")] fn test_connect_with_alpn_successful_single_match() { 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_alpn_protocols(&[b"spdy/3.1"]); 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")] fn test_connect_with_npn_successful_single_match() { 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_npn_protocols(&[b"spdy/3.1"]); 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(); // We create a different context instance for the server... 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_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); 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 mut ctx = SslContext::new(Tls).unwrap(); + let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); 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(); // We create a different context instance for the server... 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_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); 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 mut ctx = SslContext::new(Tls).unwrap(); + let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); 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(); // We create a different context instance for the server... 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_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); 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 mut ctx = SslContext::new(Tls).unwrap(); + let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); 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(); // We create a different context instance for the server... 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_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); 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()); }); - let mut ctx = SslContext::new(Tls).unwrap(); + let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); @@ -797,18 +795,15 @@ mod dtlsv1 { use std::net::TcpStream; use std::thread; - use crypto::hash::Type::SHA256; + use crypto::hash::MessageDigest; use ssl::SslMethod; - use ssl::SslMethod::Dtls; use ssl::{SslContext, SslStream}; use ssl::SSL_VERIFY_PEER; use x509::X509StoreContext; - const PROTOCOL: SslMethod = Dtls; - #[test] fn test_new_ctx() { - SslContext::new(PROTOCOL).unwrap(); + SslContext::new(SslMethod::dtls()).unwrap(); } } @@ -817,7 +812,7 @@ mod dtlsv1 { fn test_read_dtlsv1() { 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]; assert!(stream.read(&mut buf).is_ok()); } @@ -857,7 +852,7 @@ fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>) fn test_write_nonblocking() { let (_s, stream) = Server::new(); 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 iterations = 0; @@ -895,7 +890,7 @@ fn test_write_nonblocking() { fn test_read_nonblocking() { let (_s, stream) = Server::new(); 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 iterations = 0; @@ -969,7 +964,7 @@ fn write_panic() { let (_s, stream) = Server::new(); let stream = ExplodingStream(stream); - let ctx = SslContext::new(SslMethod::Tls).unwrap(); + let ctx = SslContext::new(SslMethod::tls()).unwrap(); let _ = SslStream::connect(&ctx, stream); } @@ -997,7 +992,7 @@ fn read_panic() { let (_s, stream) = Server::new(); let stream = ExplodingStream(stream); - let ctx = SslContext::new(SslMethod::Tls).unwrap(); + let ctx = SslContext::new(SslMethod::tls()).unwrap(); let _ = SslStream::connect(&ctx, stream); } @@ -1025,7 +1020,7 @@ fn flush_panic() { let (_s, stream) = Server::new(); 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 _ = stream.flush(); } @@ -1033,12 +1028,12 @@ fn flush_panic() { #[test] fn refcount_ssl_context() { let mut ssl = { - let ctx = SslContext::new(SslMethod::Tls).unwrap(); + let ctx = SslContext::new(SslMethod::tls()).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); } } @@ -1046,7 +1041,7 @@ fn refcount_ssl_context() { #[test] #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( 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_verify(SSL_VERIFY_PEER); let s = TcpStream::connect("google.com:443").unwrap(); @@ -1065,7 +1060,7 @@ fn default_verify_paths() { fn add_extra_chain_cert() { let cert = include_bytes!("../../../test/cert.pem"); 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(); } @@ -1073,7 +1068,7 @@ fn add_extra_chain_cert() { #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( #[cfg(feature = "openssl-102")] 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_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(feature = "openssl-102")] 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_verify(SSL_VERIFY_PEER); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 9fed94e2..c429b486 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -10,13 +10,10 @@ use std::slice; use std::collections::HashMap; use std::marker::PhantomData; -use HashTypeInternals; use asn1::Asn1Time; use asn1::Asn1TimeRef; - use bio::{MemBio, MemBioSlice}; -use crypto::hash; -use crypto::hash::Type as HashType; +use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rand::rand_bytes; use ffi; @@ -129,7 +126,7 @@ impl X509StoreContext { /// # Example /// /// ``` -/// use openssl::crypto::hash::Type; +/// use openssl::crypto::hash::MessageDigest; /// use openssl::crypto::pkey::PKey; /// use openssl::crypto::rsa::RSA; /// use openssl::x509::X509Generator; @@ -141,7 +138,7 @@ impl X509StoreContext { /// let gen = X509Generator::new() /// .set_valid_period(365*2) /// .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])); /// /// let cert = gen.sign(&pkey).unwrap(); @@ -152,7 +149,7 @@ pub struct X509Generator { days: u32, names: Vec<(String, String)>, extensions: Extensions, - hash_type: HashType, + hash_type: MessageDigest, } impl X509Generator { @@ -168,7 +165,7 @@ impl X509Generator { days: 365, names: vec![], extensions: Extensions::new(), - hash_type: HashType::SHA1, + hash_type: MessageDigest::sha1(), } } @@ -239,7 +236,7 @@ impl X509Generator { 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 } @@ -358,7 +355,7 @@ impl X509Generator { &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)); Ok(x509) } @@ -380,7 +377,7 @@ impl X509Generator { 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)); Ok(X509Req::new(req)) @@ -438,9 +435,9 @@ impl<'a> X509Ref<'a> { } /// 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 { - let evp = hash_type.evp_md(); + let evp = hash_type.as_ptr(); let mut len = ffi::EVP_MAX_MD_SIZE; let mut buf = vec![0u8; len as usize]; try_ssl!(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len)); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 07d9e1d4..afb06408 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,6 +1,6 @@ use serialize::hex::FromHex; -use crypto::hash::Type::SHA1; +use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rsa::RSA; use x509::{X509, X509Generator}; @@ -14,7 +14,7 @@ fn get_generator() -> X509Generator { X509Generator::new() .set_valid_period(365 * 2) .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(ExtKeyUsage(vec![ClientAuth, ServerAuth, @@ -83,7 +83,7 @@ fn test_req_gen() { fn test_cert_loading() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); - let fingerprint = cert.fingerprint(SHA1).unwrap(); + let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap(); let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let hash_vec = hash_str.from_hex().unwrap(); |