aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-08-07 16:28:29 -0700
committerSteven Fackler <[email protected]>2016-08-07 16:29:36 -0700
commit7ca5ccf0646478b6d3557b066594d7e7afc36c53 (patch)
tree5244c966b649b73fc5e599edfc31edb1b1d2224e /openssl/src
parentRefactor BigNum (diff)
downloadrust-openssl-7ca5ccf0646478b6d3557b066594d7e7afc36c53.tar.xz
rust-openssl-7ca5ccf0646478b6d3557b066594d7e7afc36c53.zip
Hash reform
Closes #430
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/crypto/dsa.rs14
-rw-r--r--openssl/src/crypto/hash.rs150
-rw-r--r--openssl/src/crypto/hmac.rs152
-rw-r--r--openssl/src/crypto/mod.rs6
-rw-r--r--openssl/src/crypto/pkcs5.rs48
-rw-r--r--openssl/src/crypto/pkey.rs2
-rw-r--r--openssl/src/crypto/rsa.rs10
-rw-r--r--openssl/src/lib.rs7
-rw-r--r--openssl/src/x509/mod.rs35
9 files changed, 192 insertions, 232 deletions
diff --git a/openssl/src/crypto/dsa.rs b/openssl/src/crypto/dsa.rs
index 84024379..099657da 100644
--- a/openssl/src/crypto/dsa.rs
+++ b/openssl/src/crypto/dsa.rs
@@ -7,7 +7,7 @@ use libc::{c_uint, c_int, c_char, c_void};
use bn::BigNumRef;
use bio::{MemBio, MemBioSlice};
use crypto::hash;
-use crypto::HashTypeInternals;
+use HashTypeInternals;
use crypto::util::{CallbackState, invoke_passwd_cb};
@@ -249,9 +249,9 @@ mod test {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let digest = {
- let mut sha = Hasher::new(Type::SHA1);
+ let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
- sha.finish()
+ sha.finish().unwrap()
};
let sig = key.sign(Type::SHA1, &digest).unwrap();
@@ -274,9 +274,9 @@ mod test {
};
let digest = {
- let mut sha = Hasher::new(Type::SHA1);
+ let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
- sha.finish()
+ sha.finish().unwrap()
};
let sig = private_key.sign(Type::SHA1, &digest).unwrap();
@@ -298,9 +298,9 @@ mod test {
};
let digest = {
- let mut sha = Hasher::new(Type::SHA1);
+ let mut sha = Hasher::new(Type::SHA1).unwrap();
sha.write_all(&input).unwrap();
- sha.finish()
+ sha.finish().unwrap()
};
let mut sig = private_key.sign(Type::SHA1, &digest).unwrap();
diff --git a/openssl/src/crypto/hash.rs b/openssl/src/crypto/hash.rs
index 69d3a350..207a55f5 100644
--- a/openssl/src/crypto/hash.rs
+++ b/openssl/src/crypto/hash.rs
@@ -1,10 +1,12 @@
use libc::c_uint;
-use std::iter::repeat;
use std::io::prelude::*;
use std::io;
+use std::ptr;
+use std::cmp;
use ffi;
-use crypto::HashTypeInternals;
+use HashTypeInternals;
+use error::ErrorStack;
use nid::Nid;
/// Message digest (hash) type.
@@ -31,26 +33,8 @@ impl HashTypeInternals for Type {
Type::RIPEMD160 => Nid::RIPEMD160,
}
}
-}
-impl Type {
- /// Returns the length of the message digest.
- #[inline]
- pub fn md_len(&self) -> usize {
- match *self {
- Type::MD5 => 16,
- Type::SHA1 => 20,
- Type::SHA224 => 28,
- Type::SHA256 => 32,
- Type::SHA384 => 48,
- Type::SHA512 => 64,
- Type::RIPEMD160 => 20,
- }
- }
-
- /// Internal interface subject to removal.
- #[inline]
- pub fn evp_md(&self) -> *const ffi::EVP_MD {
+ fn evp_md(&self) -> *const ffi::EVP_MD {
unsafe {
match *self {
Type::MD5 => ffi::EVP_md5(),
@@ -84,21 +68,20 @@ use self::State::*;
/// use openssl::crypto::hash::{hash, Type};
/// 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);
+/// let res = hash(Type::MD5, data).unwrap();
/// assert_eq!(res, spec);
/// ```
///
/// Use the `Write` trait to supply the input in chunks.
///
/// ```
-/// use std::io::prelude::*;
/// use openssl::crypto::hash::{Hasher, Type};
/// 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);
-/// h.write_all(data[0]);
-/// h.write_all(data[1]);
-/// let res = h.finish();
+/// let mut h = Hasher::new(Type::MD5).unwrap();
+/// h.update(data[0]).unwrap();
+/// h.update(data[1]).unwrap();
+/// let res = h.finish().unwrap();
/// assert_eq!(res, spec);
/// ```
///
@@ -116,14 +99,10 @@ pub struct Hasher {
impl Hasher {
/// Creates a new `Hasher` with the specified hash type.
- pub fn new(ty: Type) -> Hasher {
+ pub fn new(ty: Type) -> Result<Hasher, ErrorStack> {
ffi::init();
- let ctx = unsafe {
- let r = ffi::EVP_MD_CTX_create();
- assert!(!r.is_null());
- r
- };
+ let ctx = unsafe { try_ssl_null!(ffi::EVP_MD_CTX_create()) };
let md = ty.evp_md();
let mut h = Hasher {
@@ -132,67 +111,60 @@ impl Hasher {
type_: ty,
state: Finalized,
};
- h.init();
- h
+ try!(h.init());
+ Ok(h)
}
- #[inline]
- fn init(&mut self) {
+ fn init(&mut self) -> Result<(), ErrorStack> {
match self.state {
- Reset => return,
+ Reset => return Ok(()),
Updated => {
- self.finalize();
+ try!(self.finish());
}
Finalized => (),
}
- unsafe {
- let r = ffi::EVP_DigestInit_ex(self.ctx, self.md, 0 as *const _);
- assert_eq!(r, 1);
- }
+ unsafe { try_ssl!(ffi::EVP_DigestInit_ex(self.ctx, self.md, 0 as *const _)); }
self.state = Reset;
+ Ok(())
}
- #[inline]
- fn update(&mut self, data: &[u8]) {
+ /// Feeds data into the hasher.
+ pub fn update(&mut self, mut data: &[u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
- self.init();
+ try!(self.init());
}
- unsafe {
- let r = ffi::EVP_DigestUpdate(self.ctx, data.as_ptr(), data.len() as c_uint);
- assert_eq!(r, 1);
+ while !data.is_empty() {
+ let len = cmp::min(data.len(), c_uint::max_value() as usize);
+ unsafe {
+ try_ssl!(ffi::EVP_DigestUpdate(self.ctx, data.as_ptr(), len as c_uint));
+ }
+ data = &data[len..];
}
self.state = Updated;
+ Ok(())
}
- #[inline]
- fn finalize(&mut self) -> Vec<u8> {
+ /// Returns the hash of the data written since creation or
+ /// the last `finish` and resets the hasher.
+ pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
if self.state == Finalized {
- self.init();
+ try!(self.init());
}
- let md_len = self.type_.md_len();
- let mut res: Vec<u8> = repeat(0).take(md_len).collect();
unsafe {
- let mut len = 0;
- let r = ffi::EVP_DigestFinal_ex(self.ctx, res.as_mut_ptr(), &mut len);
+ let mut len = ffi::EVP_MAX_MD_SIZE;
+ let mut res = vec![0; len as usize];
+ try_ssl!(ffi::EVP_DigestFinal_ex(self.ctx, res.as_mut_ptr(), &mut len));
+ res.truncate(len as usize);
self.state = Finalized;
- assert_eq!(len as usize, md_len);
- assert_eq!(r, 1);
+ Ok(res)
}
- res
- }
-
- /// Returns the hash of the data written since creation or
- /// the last `finish` and resets the hasher.
- #[inline]
- pub fn finish(&mut self) -> Vec<u8> {
- self.finalize()
}
}
impl Write for Hasher {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.update(buf);
+ try!(self.update(buf));
Ok(buf.len())
}
@@ -223,9 +195,7 @@ impl Drop for Hasher {
fn drop(&mut self) {
unsafe {
if self.state != Finalized {
- let mut buf: Vec<u8> = repeat(0).take(self.type_.md_len()).collect();
- let mut len = 0;
- ffi::EVP_DigestFinal_ex(self.ctx, buf.as_mut_ptr(), &mut len);
+ drop(self.finish());
}
ffi::EVP_MD_CTX_destroy(self.ctx);
}
@@ -233,9 +203,9 @@ impl Drop for Hasher {
}
/// Computes the hash of the `data` with the hash `t`.
-pub fn hash(t: Type, data: &[u8]) -> Vec<u8> {
- let mut h = Hasher::new(t);
- let _ = h.write_all(data);
+pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
+ let mut h = try!(Hasher::new(t));
+ try!(h.update(data));
h.finish()
}
@@ -246,13 +216,13 @@ mod tests {
use std::io::prelude::*;
fn hash_test(hashtype: Type, hashtest: &(&str, &str)) {
- let res = hash(hashtype, &*hashtest.0.from_hex().unwrap());
+ let res = hash(hashtype, &*hashtest.0.from_hex().unwrap()).unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) {
- let _ = h.write_all(&*hashtest.0.from_hex().unwrap());
- let res = h.finish();
+ let _ = h.write_all(&*hashtest.0.from_hex().unwrap()).unwrap();
+ let res = h.finish().unwrap();
assert_eq!(res.to_hex(), hashtest.1);
}
@@ -294,7 +264,7 @@ mod tests {
#[test]
fn test_md5_recycle() {
- let mut h = Hasher::new(Type::MD5);
+ let mut h = Hasher::new(Type::MD5).unwrap();
for test in md5_tests.iter() {
hash_recycle_test(&mut h, test);
}
@@ -302,11 +272,11 @@ mod tests {
#[test]
fn test_finish_twice() {
- let mut h = Hasher::new(Type::MD5);
- let _ = h.write_all(&*md5_tests[6].0.from_hex().unwrap());
- let _ = h.finish();
- let res = h.finish();
- let null = hash(Type::MD5, &[]);
+ let mut h = Hasher::new(Type::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();
assert_eq!(res, null);
}
@@ -316,26 +286,26 @@ 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);
+ let h0 = Hasher::new(Type::MD5).unwrap();
println!("Clone a new hasher");
let mut h1 = h0.clone();
- let _ = h1.write_all(&inp[..p]);
+ h1.write_all(&inp[..p]).unwrap();
{
println!("Clone an updated hasher");
let mut h2 = h1.clone();
- let _ = h2.write_all(&inp[p..]);
- let res = h2.finish();
+ h2.write_all(&inp[p..]).unwrap();
+ let res = h2.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
}
- let _ = h1.write_all(&inp[p..]);
- let res = h1.finish();
+ h1.write_all(&inp[p..]).unwrap();
+ let res = h1.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i].1);
println!("Clone a finished hasher");
let mut h3 = h1.clone();
- let _ = h3.write_all(&*md5_tests[i + 1].0.from_hex().unwrap());
- let res = h3.finish();
+ h3.write_all(&*md5_tests[i + 1].0.from_hex().unwrap()).unwrap();
+ let res = h3.finish().unwrap();
assert_eq!(res.to_hex(), md5_tests[i + 1].1);
}
diff --git a/openssl/src/crypto/hmac.rs b/openssl/src/crypto/hmac.rs
index 143c7b75..453511ac 100644
--- a/openssl/src/crypto/hmac.rs
+++ b/openssl/src/crypto/hmac.rs
@@ -14,14 +14,16 @@
//
use libc::{c_int, c_uint};
-use std::iter::repeat;
use std::io;
use std::io::prelude::*;
-
-use crypto::hash::Type;
+use std::cmp;
use ffi;
use ffi_extras;
+use HashTypeInternals;
+use crypto::hash::Type;
+use error::ErrorStack;
+
#[derive(PartialEq, Copy, Clone)]
enum State {
Reset,
@@ -43,23 +45,22 @@ use self::State::*;
/// let key = b"Jefe";
/// let data = b"what do ya want for nothing?";
/// let spec = b"\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
-/// let res = hmac(Type::MD5, key, data);
+/// let res = hmac(Type::MD5, key, data).unwrap();
/// assert_eq!(res, spec);
/// ```
///
/// Use the `Write` trait to supply the input in chunks.
///
/// ```
-/// use std::io::prelude::*;
/// use openssl::crypto::hash::Type;
/// use openssl::crypto::hmac::HMAC;
/// let key = b"Jefe";
/// let data: &[&[u8]] = &[b"what do ya ", b"want for nothing?"];
/// let spec = b"\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
-/// let mut h = HMAC::new(Type::MD5, &*key);
-/// h.write_all(data[0]);
-/// h.write_all(data[1]);
-/// let res = h.finish();
+/// let mut h = HMAC::new(Type::MD5, &*key).unwrap();
+/// h.update(data[0]).unwrap();
+/// h.update(data[1]).unwrap();
+/// let res = h.finish().unwrap();
/// assert_eq!(res, spec);
/// ```
pub struct HMAC {
@@ -70,7 +71,7 @@ pub struct HMAC {
impl HMAC {
/// Creates a new `HMAC` with the specified hash type using the `key`.
- pub fn new(ty: Type, key: &[u8]) -> HMAC {
+ pub fn new(ty: Type, key: &[u8]) -> Result<HMAC, ErrorStack> {
ffi::init();
let ctx = unsafe {
@@ -85,86 +86,79 @@ impl HMAC {
type_: ty,
state: Finalized,
};
- h.init_once(md, key);
- h
+ try!(h.init_once(md, key));
+ Ok(h)
}
- #[inline]
- fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) {
+ fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) -> Result<(), ErrorStack> {
unsafe {
- let r = ffi_extras::HMAC_Init_ex(&mut self.ctx,
- key.as_ptr(),
- key.len() as c_int,
- md,
- 0 as *const _);
- assert_eq!(r, 1);
+ try_ssl!(ffi_extras::HMAC_Init_ex(&mut self.ctx,
+ key.as_ptr(),
+ key.len() as c_int,
+ md,
+ 0 as *const _));
}
self.state = Reset;
+ Ok(())
}
- #[inline]
- fn init(&mut self) {
+ fn init(&mut self) -> Result<(), ErrorStack> {
match self.state {
- Reset => return,
+ Reset => return Ok(()),
Updated => {
- self.finalize();
+ try!(self.finish());
}
Finalized => (),
}
// If the key and/or md is not supplied it's reused from the last time
// avoiding redundant initializations
unsafe {
- let r = ffi_extras::HMAC_Init_ex(&mut self.ctx,
- 0 as *const _,
- 0,
- 0 as *const _,
- 0 as *const _);
- assert_eq!(r, 1);
+ try_ssl!(ffi_extras::HMAC_Init_ex(&mut self.ctx,
+ 0 as *const _,
+ 0,
+ 0 as *const _,
+ 0 as *const _));
}
self.state = Reset;
+ Ok(())
}
- #[inline]
- fn update(&mut self, data: &[u8]) {
+ pub fn update(&mut self, mut data: &[u8]) -> Result<(), ErrorStack> {
if self.state == Finalized {
- self.init();
+ try!(self.init());
}
- unsafe {
- let r = ffi_extras::HMAC_Update(&mut self.ctx, data.as_ptr(), data.len() as c_uint);
- assert_eq!(r, 1);
+ while !data.is_empty() {
+ let len = cmp::min(data.len(), c_uint::max_value() as usize);
+ unsafe {
+ try_ssl!(ffi_extras::HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint));
+ }
+ data = &data[len..];
}
self.state = Updated;
+ Ok(())
}
- #[inline]
- fn finalize(&mut self) -> Vec<u8> {
+ /// Returns the hash of the data written since creation or
+ /// the last `finish` and resets the hasher.
+ pub fn finish(&mut self) -> Result<Vec<u8>, ErrorStack> {
if self.state == Finalized {
- self.init();
+ try!(self.init());
}
- let md_len = self.type_.md_len();
- let mut res: Vec<u8> = repeat(0).take(md_len).collect();
unsafe {
- let mut len = 0;
- let r = ffi_extras::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len);
+ let mut len = ffi::EVP_MAX_MD_SIZE;
+ let mut res = vec![0; len as usize];
+ try_ssl!(ffi_extras::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len));
+ res.truncate(len as usize);
self.state = Finalized;
- assert_eq!(len as usize, md_len);
- assert_eq!(r, 1);
+ Ok(res)
}
- res
- }
-
- /// Returns the hash of the data written since creation or
- /// the last `finish` and resets the hasher.
- #[inline]
- pub fn finish(&mut self) -> Vec<u8> {
- self.finalize()
}
}
impl Write for HMAC {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.update(buf);
+ try!(self.update(buf));
Ok(buf.len())
}
@@ -193,9 +187,7 @@ impl Drop for HMAC {
fn drop(&mut self) {
unsafe {
if self.state != Finalized {
- let mut buf: Vec<u8> = repeat(0).take(self.type_.md_len()).collect();
- let mut len = 0;
- ffi_extras::HMAC_Final(&mut self.ctx, buf.as_mut_ptr(), &mut len);
+ drop(self.finish());
}
ffi::HMAC_CTX_cleanup(&mut self.ctx);
}
@@ -203,9 +195,9 @@ impl Drop for HMAC {
}
/// Computes the HMAC of the `data` with the hash `t` and `key`.
-pub fn hmac(t: Type, key: &[u8], data: &[u8]) -> Vec<u8> {
- let mut h = HMAC::new(t, key);
- let _ = h.write_all(data);
+pub fn hmac(t: Type, key: &[u8], data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
+ let mut h = try!(HMAC::new(t, key));
+ try!(h.update(data));
h.finish()
}
@@ -220,14 +212,14 @@ mod tests {
fn test_hmac(ty: Type, tests: &[(Vec<u8>, Vec<u8>, Vec<u8>)]) {
for &(ref key, ref data, ref res) in tests.iter() {
- assert_eq!(hmac(ty, &**key, &**data), *res);
+ assert_eq!(hmac(ty, &**key, &**data).unwrap(), *res);
}
}
fn test_hmac_recycle(h: &mut HMAC, test: &(Vec<u8>, Vec<u8>, Vec<u8>)) {
let &(_, ref data, ref res) = test;
- let _ = h.write_all(&**data);
- assert_eq!(h.finish(), *res);
+ h.write_all(&**data).unwrap();
+ assert_eq!(h.finish().unwrap(), *res);
}
#[test]
@@ -273,7 +265,7 @@ mod tests {
.to_vec(),
"6f630fad67cda0ee1fb1f562db3aa53e".from_hex().unwrap())];
- let mut h = HMAC::new(MD5, &*tests[0].0);
+ let mut h = HMAC::new(MD5, &*tests[0].0).unwrap();
for i in 0..100usize {
let test = &tests[i % 2];
test_hmac_recycle(&mut h, test);
@@ -287,11 +279,11 @@ mod tests {
b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(),
"6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd".from_hex().unwrap());
- let mut h = HMAC::new(Type::MD5, &*test.0);
- let _ = h.write_all(&*test.1);
- let _ = h.finish();
- let res = h.finish();
- let null = hmac(Type::MD5, &*test.0, &[]);
+ let mut h = HMAC::new(Type::MD5, &*test.0).unwrap();
+ h.write_all(&*test.1).unwrap();
+ h.finish().unwrap();
+ let res = h.finish().unwrap();
+ let null = hmac(Type::MD5, &*test.0, &[]).unwrap();
assert_eq!(res, null);
}
@@ -307,26 +299,26 @@ mod tests {
.to_vec(),
"6f630fad67cda0ee1fb1f562db3aa53e".from_hex().unwrap())];
let p = tests[0].0.len() / 2;
- let h0 = HMAC::new(Type::MD5, &*tests[0].0);
+ let h0 = HMAC::new(Type::MD5, &*tests[0].0).unwrap();
println!("Clone a new hmac");
let mut h1 = h0.clone();
- let _ = h1.write_all(&tests[0].1[..p]);
+ h1.write_all(&tests[0].1[..p]).unwrap();
{
println!("Clone an updated hmac");
let mut h2 = h1.clone();
- let _ = h2.write_all(&tests[0].1[p..]);
- let res = h2.finish();
+ h2.write_all(&tests[0].1[p..]).unwrap();
+ let res = h2.finish().unwrap();
assert_eq!(res, tests[0].2);
}
- let _ = h1.write_all(&tests[0].1[p..]);
- let res = h1.finish();
+ h1.write_all(&tests[0].1[p..]).unwrap();
+ let res = h1.finish().unwrap();
assert_eq!(res, tests[0].2);
println!("Clone a finished hmac");
let mut h3 = h1.clone();
- let _ = h3.write_all(&*tests[1].1);
- let res = h3.finish();
+ h3.write_all(&*tests[1].1).unwrap();
+ let res = h3.finish().unwrap();
assert_eq!(res, tests[1].2);
}
@@ -373,7 +365,7 @@ mod tests {
.to_vec(),
"e8e99d0f45237d786d6bbaa7965c7808bbff1a91".from_hex().unwrap())];
- let mut h = HMAC::new(SHA1, &*tests[0].0);
+ let mut h = HMAC::new(SHA1, &*tests[0].0).unwrap();
for i in 0..100usize {
let test = &tests[i % 2];
test_hmac_recycle(&mut h, test);
@@ -399,11 +391,11 @@ mod tests {
.to_vec())];
for (&(ref key, ref data), res) in tests.iter().zip(results.iter()) {
- assert_eq!(hmac(ty, &**key, &**data), *res);
+ assert_eq!(hmac(ty, &**key, &**data).unwrap(), *res);
}
// recycle test
- let mut h = HMAC::new(ty, &*tests[5].0);
+ let mut h = HMAC::new(ty, &*tests[5].0).unwrap();
for i in 0..100usize {
let test = &tests[4 + i % 2];
let tup = (test.0.clone(), test.1.clone(), results[4 + i % 2].clone());
diff --git a/openssl/src/crypto/mod.rs b/openssl/src/crypto/mod.rs
index 5b891ce7..873f9d47 100644
--- a/openssl/src/crypto/mod.rs
+++ b/openssl/src/crypto/mod.rs
@@ -14,8 +14,6 @@
// limitations under the License.
//
-use nid::Nid;
-
pub mod hash;
pub mod hmac;
pub mod pkcs5;
@@ -28,7 +26,3 @@ pub mod dsa;
mod util;
mod symm_internal;
-
-trait HashTypeInternals {
- fn as_nid(&self) -> Nid;
-}
diff --git a/openssl/src/crypto/pkcs5.rs b/openssl/src/crypto/pkcs5.rs
index 0ba005cc..e23909d1 100644
--- a/openssl/src/crypto/pkcs5.rs
+++ b/openssl/src/crypto/pkcs5.rs
@@ -1,10 +1,12 @@
use libc::c_int;
-use std::ptr::null;
+use std::ptr;
+use ffi;
+use HashTypeInternals;
use crypto::symm_internal::evpc;
use crypto::hash;
use crypto::symm;
-use ffi;
+use error::ErrorStack;
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct KeyIvPair {
@@ -27,7 +29,7 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type,
data: &[u8],
salt: Option<&[u8]>,
count: u32)
- -> KeyIvPair {
+ -> Result<KeyIvPair, ErrorStack> {
unsafe {
@@ -36,30 +38,40 @@ pub fn evp_bytes_to_key_pbkdf1_compatible(typ: symm::Type,
assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize);
salt.as_ptr()
}
- None => null(),
+ None => ptr::null(),
};
ffi::init();
- let (evp, keylen, _) = evpc(typ);
+ let (evp, _, _) = evpc(typ);
let message_digest = message_digest_type.evp_md();
- let mut key = vec![0; keylen as usize];
- let mut iv = vec![0; keylen as usize];
+ let len = ffi::EVP_BytesToKey(evp,
+ message_digest,
+ salt_ptr,
+ data.as_ptr(),
+ data.len() as c_int,
+ count as c_int,
+ ptr::null_mut(),
+ ptr::null_mut());
+ if len == 0 {
+ return Err(ErrorStack::get());
+ }
+ let mut key = vec![0; len as usize];
+ let mut iv = vec![0; len as usize];
- let ret: c_int = ffi::EVP_BytesToKey(evp,
- message_digest,
- salt_ptr,
- data.as_ptr(),
- data.len() as c_int,
- count as c_int,
- key.as_mut_ptr(),
- iv.as_mut_ptr());
- assert!(ret == keylen as c_int);
+ try_ssl!(ffi::EVP_BytesToKey(evp,
+ message_digest,
+ salt_ptr,
+ data.as_ptr(),
+ data.len() as c_int,
+ count as c_int,
+ key.as_mut_ptr(),
+ iv.as_mut_ptr()));
- KeyIvPair { key: key, iv: iv }
+ Ok(KeyIvPair { key: key, iv: iv })
}
}
@@ -257,7 +269,7 @@ mod tests {
hash::Type::SHA1,
&data,
Some(&salt),
- 1),
+ 1).unwrap(),
super::KeyIvPair {
key: expected_key,
iv: expected_iv,
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index 9a3e140a..2a928b23 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -4,7 +4,7 @@ use std::mem;
use std::ptr;
use bio::{MemBio, MemBioSlice};
-use crypto::HashTypeInternals;
+use HashTypeInternals;
use crypto::hash;
use crypto::hash::Type as HashType;
use ffi;
diff --git a/openssl/src/crypto/rsa.rs b/openssl/src/crypto/rsa.rs
index 73239731..c9433b10 100644
--- a/openssl/src/crypto/rsa.rs
+++ b/openssl/src/crypto/rsa.rs
@@ -6,7 +6,7 @@ use libc::{c_int, c_void, c_char};
use bn::{BigNum, BigNumRef};
use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
-use crypto::HashTypeInternals;
+use HashTypeInternals;
use crypto::hash;
use crypto::util::{CallbackState, invoke_passwd_cb};
@@ -262,9 +262,9 @@ mod test {
let key = include_bytes!("../../test/rsa.pem");
let private_key = RSA::private_key_from_pem(key).unwrap();
- let mut sha = Hasher::new(Type::SHA256);
+ let mut sha = Hasher::new(Type::SHA256).unwrap();
sha.write_all(&signing_input_rs256()).unwrap();
- let digest = sha.finish();
+ let digest = sha.finish().unwrap();
let result = private_key.sign(Type::SHA256, &digest).unwrap();
@@ -276,9 +276,9 @@ mod test {
let key = include_bytes!("../../test/rsa.pem.pub");
let public_key = RSA::public_key_from_pem(key).unwrap();
- let mut sha = Hasher::new(Type::SHA256);
+ let mut sha = Hasher::new(Type::SHA256).unwrap();
sha.write_all(&signing_input_rs256()).unwrap();
- let digest = sha.finish();
+ let digest = sha.finish().unwrap();
let result = public_key.verify(Type::SHA256, &digest, &signature_rs256()).unwrap();
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs
index 4cd76613..8dc73dde 100644
--- a/openssl/src/lib.rs
+++ b/openssl/src/lib.rs
@@ -14,6 +14,8 @@ extern crate rustc_serialize as serialize;
#[cfg(test)]
extern crate net2;
+use nid::Nid;
+
mod macros;
pub mod asn1;
@@ -26,3 +28,8 @@ 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/x509/mod.rs b/openssl/src/x509/mod.rs
index 82448212..22182d32 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -1,7 +1,5 @@
-use libc::{c_char, c_int, c_long, c_ulong, c_uint, c_void};
-use std::cmp::Ordering;
+use libc::{c_char, c_int, c_long, c_ulong, c_void};
use std::ffi::CString;
-use std::iter::repeat;
use std::mem;
use std::ptr;
use std::ops::Deref;
@@ -11,6 +9,7 @@ use std::slice;
use std::collections::HashMap;
use std::marker::PhantomData;
+use HashTypeInternals;
use asn1::Asn1Time;
use bio::{MemBio, MemBioSlice};
use crypto::hash;
@@ -434,28 +433,14 @@ impl<'a> X509Ref<'a> {
}
/// Returns certificate fingerprint calculated using provided hash
- pub fn fingerprint(&self, hash_type: hash::Type) -> Option<Vec<u8>> {
- let evp = hash_type.evp_md();
- let len = hash_type.md_len();
- let v: Vec<u8> = repeat(0).take(len as usize).collect();
- let act_len: c_uint = 0;
- let res = unsafe {
- ffi::X509_digest(self.0,
- evp,
- mem::transmute(v.as_ptr()),
- mem::transmute(&act_len))
- };
-
- match res {
- 0 => None,
- _ => {
- let act_len = act_len as usize;
- match len.cmp(&act_len) {
- Ordering::Greater => None,
- Ordering::Equal => Some(v),
- Ordering::Less => panic!("Fingerprint buffer was corrupted!"),
- }
- }
+ pub fn fingerprint(&self, hash_type: hash::Type) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let evp = hash_type.evp_md();
+ 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));
+ buf.truncate(len as usize);
+ Ok(buf)
}
}