Loading openssl-sys/src/lib.rs +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading openssl/src/crypto/dsa.rs +3 −107 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 } Loading Loading @@ -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] Loading openssl/src/crypto/pkey.rs +12 −0 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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 { Loading openssl/src/crypto/sign.rs +56 −3 Original line number Diff line number Diff line Loading @@ -113,6 +113,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) } } Loading Loading @@ -213,6 +215,7 @@ mod test { use crypto::hash::Type; use crypto::sign::{Signer, Verifier}; use crypto::rsa::RSA; use crypto::dsa::DSA; use crypto::pkey::PKey; static INPUT: &'static [u8] = Loading Loading @@ -240,7 +243,7 @@ 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(); Loading @@ -253,7 +256,7 @@ 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(); Loading @@ -264,7 +267,7 @@ mod test { } #[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(); Loading @@ -275,6 +278,56 @@ mod test { assert!(!verifier.finish(SIGNATURE).unwrap()); } #[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(Type::SHA1, &private_key).unwrap(); signer.update(&input).unwrap(); let sig = signer.finish().unwrap(); let mut verifier = Verifier::new(Type::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(Type::SHA1, &private_key).unwrap(); signer.update(&input).unwrap(); let mut sig = signer.finish().unwrap(); sig[0] -= 1; let mut verifier = Verifier::new(Type::SHA1, &public_key).unwrap(); verifier.update(&input).unwrap(); match verifier.finish(&sig) { Ok(true) => panic!("unexpected success"), Ok(false) | Err(_) => {}, } } fn test_hmac(ty: Type, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) { for &(ref key, ref data, ref res) in tests.iter() { let pkey = PKey::hmac(key).unwrap(); Loading Loading
openssl-sys/src/lib.rs +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
openssl/src/crypto/dsa.rs +3 −107 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 } Loading Loading @@ -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] Loading
openssl/src/crypto/pkey.rs +12 −0 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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 { Loading
openssl/src/crypto/sign.rs +56 −3 Original line number Diff line number Diff line Loading @@ -113,6 +113,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) } } Loading Loading @@ -213,6 +215,7 @@ mod test { use crypto::hash::Type; use crypto::sign::{Signer, Verifier}; use crypto::rsa::RSA; use crypto::dsa::DSA; use crypto::pkey::PKey; static INPUT: &'static [u8] = Loading Loading @@ -240,7 +243,7 @@ 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(); Loading @@ -253,7 +256,7 @@ 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(); Loading @@ -264,7 +267,7 @@ mod test { } #[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(); Loading @@ -275,6 +278,56 @@ mod test { assert!(!verifier.finish(SIGNATURE).unwrap()); } #[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(Type::SHA1, &private_key).unwrap(); signer.update(&input).unwrap(); let sig = signer.finish().unwrap(); let mut verifier = Verifier::new(Type::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(Type::SHA1, &private_key).unwrap(); signer.update(&input).unwrap(); let mut sig = signer.finish().unwrap(); sig[0] -= 1; let mut verifier = Verifier::new(Type::SHA1, &public_key).unwrap(); verifier.update(&input).unwrap(); match verifier.finish(&sig) { Ok(true) => panic!("unexpected success"), Ok(false) | Err(_) => {}, } } fn test_hmac(ty: Type, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) { for &(ref key, ref data, ref res) in tests.iter() { let pkey = PKey::hmac(key).unwrap(); Loading