aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-03-11 20:01:03 +0100
committerlloyd <[email protected]>2013-03-11 20:01:03 +0100
commit3ef8dc772b1e031f2926ddd873e746f8de88324f (patch)
tree7421a64a49ebcf969413303cd093cdd61e4ddb5e
parentAdd support for PKCS #1 v1.5 RSA encryption (diff)
downloadrust-openssl-3ef8dc772b1e031f2926ddd873e746f8de88324f.tar.xz
rust-openssl-3ef8dc772b1e031f2926ddd873e746f8de88324f.zip
Add support for RSA signing with alternate hashes (MD5, SHA-512, etc)
-rw-r--r--pkey.rs49
1 files changed, 39 insertions, 10 deletions
diff --git a/pkey.rs b/pkey.rs
index 6b942d77..2d253eca 100644
--- a/pkey.rs
+++ b/pkey.rs
@@ -1,4 +1,5 @@
use libc::{c_int, c_uint};
+use hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512};
#[allow(non_camel_case_types)]
type EVP_PKEY = *libc::c_void;
@@ -62,6 +63,17 @@ fn openssl_padding_code(padding: EncryptionPadding) -> c_int {
}
}
+fn openssl_hash_nid(hash: HashType) -> c_int {
+ match hash {
+ MD5 => 4, // NID_md5,
+ SHA1 => 64, // NID_sha1
+ SHA224 => 675, // NID_sha224
+ SHA256 => 672, // NID_sha256
+ SHA384 => 673, // NID_sha384
+ SHA512 => 674, // NID_sha512
+ }
+}
+
fn rsa_to_any(rsa: *RSA) -> *ANYKEY unsafe {
cast::reinterpret_cast(&rsa)
}
@@ -268,7 +280,15 @@ pub impl PKey {
* Signs data, using OpenSSL's default scheme and sha256. Unlike encrypt(),
* can process an arbitrary amount of data; returns the signature.
*/
- fn sign(s: &[u8]) -> ~[u8] unsafe {
+ fn sign(s: &[u8]) -> ~[u8] unsafe { self.sign_with_hash(s, SHA256) }
+
+ /**
+ * Verifies a signature s (using OpenSSL's default scheme and sha256) on a
+ * message m. Returns true if the signature is valid, and false otherwise.
+ */
+ fn verify(m: &[u8], s: &[u8]) -> bool unsafe { self.verify_with_hash(m, s, SHA256) }
+
+ fn sign_with_hash(s: &[u8], hash: HashType) -> ~[u8] unsafe {
let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp);
let len = libcrypto::RSA_size(rsa);
let mut r = vec::from_elem(len as uint + 1u, 0u8);
@@ -277,9 +297,8 @@ pub impl PKey {
do vec::as_imm_buf(s) |ps, s_len| {
let plen = ptr::addr_of(&len);
- // XXX: 672 == NID_sha256
let rv = libcrypto::RSA_sign(
- 672 as c_int,
+ openssl_hash_nid(hash),
ps,
s_len as c_uint,
pr,
@@ -295,18 +314,13 @@ pub impl PKey {
}
}
- /**
- * Verifies a signature s (using OpenSSL's default scheme and sha256) on a
- * message m. Returns true if the signature is valid, and false otherwise.
- */
- fn verify(m: &[u8], s: &[u8]) -> bool unsafe {
+ fn verify_with_hash(m: &[u8], s: &[u8], hash: HashType) -> bool unsafe {
let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp);
do vec::as_imm_buf(m) |pm, m_len| {
do vec::as_imm_buf(s) |ps, s_len| {
- // XXX: 672 == NID_sha256
let rv = libcrypto::RSA_verify(
- 672 as c_int,
+ openssl_hash_nid(hash),
pm,
m_len as c_uint,
ps,
@@ -393,4 +407,19 @@ mod tests {
let rv = k1.verify(msg, sig);
assert(rv == true);
}
+
+ #[test]
+ fn test_sign_hashes() {
+ let k0 = PKey();
+ let k1 = PKey();
+ let msg = ~[0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
+ k0.gen(512u);
+ k1.load_pub(k0.save_pub());
+
+ let sig = k0.sign_with_hash(msg, MD5);
+
+ assert k1.verify_with_hash(msg, sig, MD5);
+ assert !k1.verify_with_hash(msg, sig, SHA1);
+ }
+
}