Commit fdb41310 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #475 from sfackler/no-enums

Turn enums into structs
parents 228b8fbc 6ea551dc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ dist: trusty
env:
  global:
    - TARGET=x86_64-unknown-linux-gnu
    - BUILD_OPENSSL_VERSION=1.0.1u
matrix:
  include:
    # ARM-bit version compat
@@ -44,7 +45,6 @@ matrix:
    - rust: nightly

    # 64-bit version compat
    - env: BUILD_OPENSSL_VERSION=1.0.1u
    - env: BUILD_OPENSSL_VERSION=1.0.2h
    - env: BUILD_OPENSSL_VERSION=1.1.0b

+2 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
+3 −107
Original line number Diff line number Diff line
@@ -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]
+61 −51
Original line number Diff line number Diff line
@@ -8,47 +8,56 @@ use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
#[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free};

use HashTypeInternals;
use error::ErrorStack;
use nid::Nid;

/// Message digest (hash) type.
#[derive(Copy, Clone)]
pub enum Type {
    MD5,
    SHA1,
    SHA224,
    SHA256,
    SHA384,
    SHA512,
    RIPEMD160,
}

impl HashTypeInternals for Type {
    fn as_nid(&self) -> Nid {
        match *self {
            Type::MD5 => Nid::MD5,
            Type::SHA1 => Nid::SHA1,
            Type::SHA224 => Nid::SHA224,
            Type::SHA256 => Nid::SHA256,
            Type::SHA384 => Nid::SHA384,
            Type::SHA512 => Nid::SHA512,
            Type::RIPEMD160 => Nid::RIPEMD160,
        }
    }

    fn evp_md(&self) -> *const ffi::EVP_MD {
pub struct MessageDigest(*const ffi::EVP_MD);

impl MessageDigest {
    pub fn md5() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_md5())
        }
    }

    pub fn sha1() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_sha1())
        }
    }

    pub fn sha224() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_sha224())
        }
    }

    pub fn sha256() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_sha256())
        }
    }

    pub fn sha384() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_sha384())
        }
    }

    pub fn sha512() -> MessageDigest {
        unsafe {
            match *self {
                Type::MD5 => ffi::EVP_md5(),
                Type::SHA1 => ffi::EVP_sha1(),
                Type::SHA224 => ffi::EVP_sha224(),
                Type::SHA256 => ffi::EVP_sha256(),
                Type::SHA384 => ffi::EVP_sha384(),
                Type::SHA512 => ffi::EVP_sha512(),
                Type::RIPEMD160 => ffi::EVP_ripemd160(),
            MessageDigest(ffi::EVP_sha512())
        }
    }

    pub fn ripemd160() -> MessageDigest {
        unsafe {
            MessageDigest(ffi::EVP_ripemd160())
        }
    }

    pub fn as_ptr(&self) -> *const ffi::EVP_MD {
        self.0
    }
}

@@ -68,20 +77,22 @@ use self::State::*;
/// Calculate a hash in one go.
///
/// ```
/// use openssl::crypto::hash::{hash, Type};
/// use openssl::crypto::hash::{hash, MessageDigest};
///
/// 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).unwrap();
/// let res = hash(MessageDigest::md5(), data).unwrap();
/// assert_eq!(res, spec);
/// ```
///
/// Use the `Write` trait to supply the input in chunks.
///
/// ```
/// use openssl::crypto::hash::{Hasher, Type};
/// use openssl::crypto::hash::{Hasher, MessageDigest};
///
/// 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).unwrap();
/// let mut h = Hasher::new(MessageDigest::md5()).unwrap();
/// h.update(data[0]).unwrap();
/// h.update(data[1]).unwrap();
/// let res = h.finish().unwrap();
@@ -96,21 +107,20 @@ use self::State::*;
pub struct Hasher {
    ctx: *mut ffi::EVP_MD_CTX,
    md: *const ffi::EVP_MD,
    type_: Type,
    type_: MessageDigest,
    state: State,
}

impl Hasher {
    /// Creates a new `Hasher` with the specified hash type.
    pub fn new(ty: Type) -> Result<Hasher, ErrorStack> {
    pub fn new(ty: MessageDigest) -> Result<Hasher, ErrorStack> {
        ffi::init();

        let ctx = unsafe { try_ssl_null!(EVP_MD_CTX_new()) };
        let md = ty.evp_md();

        let mut h = Hasher {
            ctx: ctx,
            md: md,
            md: ty.as_ptr(),
            type_: ty,
            state: Finalized,
        };
@@ -204,7 +214,7 @@ impl Drop for Hasher {
}

/// Computes the hash of the `data` with the hash `t`.
pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
pub fn hash(t: MessageDigest, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
    let mut h = try!(Hasher::new(t));
    try!(h.update(data));
    h.finish()
@@ -213,10 +223,10 @@ pub fn hash(t: Type, data: &[u8]) -> Result<Vec<u8>, ErrorStack> {
#[cfg(test)]
mod tests {
    use serialize::hex::{FromHex, ToHex};
    use super::{hash, Hasher, Type};
    use super::{hash, Hasher, MessageDigest};
    use std::io::prelude::*;

    fn hash_test(hashtype: Type, hashtest: &(&str, &str)) {
    fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) {
        let res = hash(hashtype, &*hashtest.0.from_hex().unwrap()).unwrap();
        assert_eq!(res.to_hex(), hashtest.1);
    }
@@ -259,13 +269,13 @@ mod tests {
    #[test]
    fn test_md5() {
        for test in md5_tests.iter() {
            hash_test(Type::MD5, test);
            hash_test(MessageDigest::md5(), test);
        }
    }

    #[test]
    fn test_md5_recycle() {
        let mut h = Hasher::new(Type::MD5).unwrap();
        let mut h = Hasher::new(MessageDigest::md5()).unwrap();
        for test in md5_tests.iter() {
            hash_recycle_test(&mut h, test);
        }
@@ -273,11 +283,11 @@ mod tests {

    #[test]
    fn test_finish_twice() {
        let mut h = Hasher::new(Type::MD5).unwrap();
        let mut h = Hasher::new(MessageDigest::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();
        let null = hash(MessageDigest::md5(), &[]).unwrap();
        assert_eq!(res, null);
    }

@@ -287,7 +297,7 @@ 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).unwrap();
        let h0 = Hasher::new(MessageDigest::md5()).unwrap();

        println!("Clone a new hasher");
        let mut h1 = h0.clone();
@@ -315,7 +325,7 @@ mod tests {
        let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")];

        for test in tests.iter() {
            hash_test(Type::SHA1, test);
            hash_test(MessageDigest::sha1(), test);
        }
    }

@@ -325,7 +335,7 @@ mod tests {
                      "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")];

        for test in tests.iter() {
            hash_test(Type::SHA256, test);
            hash_test(MessageDigest::sha256(), test);
        }
    }

@@ -334,7 +344,7 @@ mod tests {
        let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")];

        for test in tests.iter() {
            hash_test(Type::RIPEMD160, test);
            hash_test(MessageDigest::ripemd160(), test);
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ mod compat {

#[cfg(test)]
mod test {
    use crypto::hash::Type::SHA1;
    use crypto::hash::MessageDigest;
    use serialize::hex::ToHex;

    use super::*;
@@ -108,11 +108,11 @@ mod test {
        let pkcs12 = Pkcs12::from_der(der).unwrap();
        let parsed = pkcs12.parse("mypass").unwrap();

        assert_eq!(parsed.cert.fingerprint(SHA1).unwrap().to_hex(),
        assert_eq!(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
                   "59172d9313e84459bcff27f967e79e6e9217e584");

        assert_eq!(parsed.chain.len(), 1);
        assert_eq!(parsed.chain[0].fingerprint(SHA1).unwrap().to_hex(),
        assert_eq!(parsed.chain[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
                   "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
    }
}
Loading