aboutsummaryrefslogtreecommitdiff
path: root/hash.rs
diff options
context:
space:
mode:
Diffstat (limited to 'hash.rs')
-rw-r--r--hash.rs98
1 files changed, 52 insertions, 46 deletions
diff --git a/hash.rs b/hash.rs
index 88f75f67..2a43cbd2 100644
--- a/hash.rs
+++ b/hash.rs
@@ -1,5 +1,7 @@
use std::libc::c_uint;
-use std::{libc,vec,ptr};
+use std::libc;
+use std::ptr;
+use std::vec;
pub enum HashType {
MD5,
@@ -16,32 +18,37 @@ pub type EVP_MD_CTX = *libc::c_void;
#[allow(non_camel_case_types)]
pub type EVP_MD = *libc::c_void;
-#[abi = "cdecl"]
-#[link_args = "-lcrypto"]
-extern {
- fn EVP_MD_CTX_create() -> EVP_MD_CTX;
-
- fn EVP_md5() -> EVP_MD;
- fn EVP_sha1() -> EVP_MD;
- fn EVP_sha224() -> EVP_MD;
- fn EVP_sha256() -> EVP_MD;
- fn EVP_sha384() -> EVP_MD;
- fn EVP_sha512() -> EVP_MD;
-
- fn EVP_DigestInit(ctx: EVP_MD_CTX, typ: EVP_MD);
- fn EVP_DigestUpdate(ctx: EVP_MD_CTX, data: *u8, n: c_uint);
- fn EVP_DigestFinal(ctx: EVP_MD_CTX, res: *mut u8, n: *u32);
+mod libcrypto {
+ use super::*;
+ use std::libc::c_uint;
+
+ #[link_args = "-lcrypto"]
+ extern {
+ fn EVP_MD_CTX_create() -> EVP_MD_CTX;
+ fn EVP_MD_CTX_destroy(ctx: EVP_MD_CTX);
+
+ fn EVP_md5() -> EVP_MD;
+ fn EVP_sha1() -> EVP_MD;
+ fn EVP_sha224() -> EVP_MD;
+ fn EVP_sha256() -> EVP_MD;
+ fn EVP_sha384() -> EVP_MD;
+ fn EVP_sha512() -> EVP_MD;
+
+ fn EVP_DigestInit(ctx: EVP_MD_CTX, typ: EVP_MD);
+ fn EVP_DigestUpdate(ctx: EVP_MD_CTX, data: *u8, n: c_uint);
+ fn EVP_DigestFinal(ctx: EVP_MD_CTX, res: *mut u8, n: *u32);
+ }
}
pub fn evpmd(t: HashType) -> (EVP_MD, uint) {
unsafe {
match t {
- MD5 => (EVP_md5(), 16u),
- SHA1 => (EVP_sha1(), 20u),
- SHA224 => (EVP_sha224(), 28u),
- SHA256 => (EVP_sha256(), 32u),
- SHA384 => (EVP_sha384(), 48u),
- SHA512 => (EVP_sha512(), 64u),
+ MD5 => (libcrypto::EVP_md5(), 16u),
+ SHA1 => (libcrypto::EVP_sha1(), 20u),
+ SHA224 => (libcrypto::EVP_sha224(), 28u),
+ SHA256 => (libcrypto::EVP_sha256(), 32u),
+ SHA384 => (libcrypto::EVP_sha384(), 48u),
+ SHA512 => (libcrypto::EVP_sha512(), 64u),
}
}
}
@@ -52,29 +59,22 @@ pub struct Hasher {
priv len: uint,
}
-pub fn Hasher(ht: HashType) -> Hasher {
- unsafe {
- let ctx = EVP_MD_CTX_create();
- let (evp, mdlen) = evpmd(ht);
- let h = Hasher { evp: evp, ctx: ctx, len: mdlen };
- h.init();
- h
- }
-}
-
impl Hasher {
- /// Initializes this hasher
- pub fn init(&self) {
+ pub fn new(ht: HashType) -> Hasher {
+ let ctx = unsafe { libcrypto::EVP_MD_CTX_create() };
+ let (evp, mdlen) = evpmd(ht);
unsafe {
- EVP_DigestInit(self.ctx, self.evp);
+ libcrypto::EVP_DigestInit(ctx, evp);
}
+
+ Hasher { evp: evp, ctx: ctx, len: mdlen }
}
/// Update this hasher with more input bytes
pub fn update(&self, data: &[u8]) {
- unsafe {
- do data.as_imm_buf |pdata, len| {
- EVP_DigestUpdate(self.ctx, pdata, len as c_uint)
+ do data.as_imm_buf |pdata, len| {
+ unsafe {
+ libcrypto::EVP_DigestUpdate(self.ctx, pdata, len as c_uint)
}
}
}
@@ -84,12 +84,20 @@ impl Hasher {
* initialization
*/
pub fn final(&self) -> ~[u8] {
- unsafe {
- let mut res = vec::from_elem(self.len, 0u8);
- do res.as_mut_buf |pres, _len| {
- EVP_DigestFinal(self.ctx, pres, ptr::null());
+ let mut res = vec::from_elem(self.len, 0u8);
+ do res.as_mut_buf |pres, _len| {
+ unsafe {
+ libcrypto::EVP_DigestFinal(self.ctx, pres, ptr::null());
}
- res
+ }
+ res
+ }
+}
+
+impl Drop for Hasher {
+ fn drop(&self) {
+ unsafe {
+ libcrypto::EVP_MD_CTX_destroy(self.ctx);
}
}
}
@@ -99,7 +107,7 @@ impl Hasher {
* value
*/
pub fn hash(t: HashType, data: &[u8]) -> ~[u8] {
- let h = Hasher(t);
+ let h = Hasher::new(t);
h.update(data);
h.final()
}
@@ -135,7 +143,6 @@ mod tests {
// Test vectors from http://www.nsrl.nist.gov/testdata/
#[test]
fn test_md5() {
-
let tests = [
HashTest(~"", ~"D41D8CD98F00B204E9800998ECF8427E"),
HashTest(~"7F", ~"83ACB6E67E50E31DB6ED341DD2DE1595"),
@@ -158,7 +165,6 @@ mod tests {
#[test]
fn test_sha1() {
-
let tests = [
HashTest(~"616263", ~"A9993E364706816ABA3E25717850C26C9CD0D89D"),
];