diff options
Diffstat (limited to 'hash.rs')
| -rw-r--r-- | hash.rs | 98 |
1 files changed, 52 insertions, 46 deletions
@@ -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"), ]; |