aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-10-15 15:02:02 -0700
committerSteven Fackler <[email protected]>2016-10-15 15:02:02 -0700
commit6609a81685bfd205da024523ccc395750c3fd7f3 (patch)
tree711d819b1db7d68007899edf49230b44671c54e0 /openssl/src
parentCorrectly bind BIO_new_mem_buf (diff)
downloadrust-openssl-6609a81685bfd205da024523ccc395750c3fd7f3.tar.xz
rust-openssl-6609a81685bfd205da024523ccc395750c3fd7f3.zip
Migrate DSA sign/verify to EVP APIs
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/crypto/dsa.rs110
-rw-r--r--openssl/src/crypto/pkey.rs12
-rw-r--r--openssl/src/crypto/sign.rs59
3 files changed, 71 insertions, 110 deletions
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/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/sign.rs b/openssl/src/crypto/sign.rs
index c5d54597..24078fdc 100644
--- a/openssl/src/crypto/sign.rs
+++ b/openssl/src/crypto/sign.rs
@@ -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)
}
}
@@ -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] =
@@ -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();
@@ -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();
@@ -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();
@@ -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();