From b0fd95676f36902a601bf95fb49d87ff474ef2a5 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 19:08:15 +0100 Subject: [PATCH 01/23] Add support for PKCS #1 v1.5 RSA encryption Like it or not, needed for compatability with a lot of existing protocols. The default for encrypt/decrypt remains OAEP of course. --- pkey.rs | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/pkey.rs b/pkey.rs index 5fe399b0..6b942d77 100644 --- a/pkey.rs +++ b/pkey.rs @@ -49,6 +49,19 @@ pub enum Role { Verify } +#[doc = "Type of encryption padding to use."] +pub enum EncryptionPadding { + OAEP, + PKCS1v15 +} + +fn openssl_padding_code(padding: EncryptionPadding) -> c_int { + match padding { + OAEP => 4, + PKCS1v15 => 1 + } +} + fn rsa_to_any(rsa: *RSA) -> *ANYKEY unsafe { cast::reinterpret_cast(&rsa) } @@ -186,27 +199,22 @@ pub impl PKey { len as uint - 41u } - /** - * Encrypts data using OAEP padding, returning the encrypted data. The - * supplied data must not be larger than max_data(). - */ - fn encrypt(s: &[u8]) -> ~[u8] unsafe { + fn encrypt_with_padding(s: &[u8], padding: EncryptionPadding) -> ~[u8] unsafe { let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); let len = libcrypto::RSA_size(rsa); - // 41 comes from RSA_public_encrypt(3) for OAEP - assert s.len() < libcrypto::RSA_size(rsa) as uint - 41u; + assert s.len() < self.max_data(); let mut r = vec::from_elem(len as uint + 1u, 0u8); do vec::as_mut_buf(r) |pr, _len| { do vec::as_imm_buf(s) |ps, s_len| { - // XXX: 4 == RSA_PKCS1_OAEP_PADDING let rv = libcrypto::RSA_public_encrypt( s_len as c_uint, ps, pr, - rsa, 4 as c_int + rsa, + openssl_padding_code(padding) ); if rv < 0 as c_int { @@ -218,10 +226,7 @@ pub impl PKey { } } - /** - * Decrypts data, expecting OAEP padding, returning the decrypted data. - */ - fn decrypt(s: &[u8]) -> ~[u8] unsafe { + fn decrypt_with_padding(s: &[u8], padding: EncryptionPadding) -> ~[u8] unsafe { let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); let len = libcrypto::RSA_size(rsa); @@ -231,13 +236,12 @@ pub impl PKey { do vec::as_mut_buf(r) |pr, _len| { do vec::as_imm_buf(s) |ps, s_len| { - // XXX: 4 == RSA_PKCS1_OAEP_PADDING let rv = libcrypto::RSA_private_decrypt( s_len as c_uint, ps, pr, rsa, - 4 as c_int + openssl_padding_code(padding) ); if rv < 0 as c_int { @@ -249,6 +253,17 @@ pub impl PKey { } } + /** + * Encrypts data using OAEP padding, returning the encrypted data. The + * supplied data must not be larger than max_data(). + */ + fn encrypt(s: &[u8]) -> ~[u8] unsafe { self.encrypt_with_padding(s, OAEP) } + + /** + * Decrypts data, expecting OAEP padding, returning the decrypted data. + */ + fn decrypt(s: &[u8]) -> ~[u8] unsafe { self.decrypt_with_padding(s, OAEP) } + /** * Signs data, using OpenSSL's default scheme and sha256. Unlike encrypt(), * can process an arbitrary amount of data; returns the signature. @@ -355,6 +370,18 @@ mod tests { assert(msg == dmsg); } + #[test] + fn test_encrypt_pkcs() { + let k0 = PKey(); + let k1 = PKey(); + let msg = ~[0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; + k0.gen(512u); + k1.load_pub(k0.save_pub()); + let emsg = k1.encrypt_with_padding(msg, PKCS1v15); + let dmsg = k0.decrypt_with_padding(emsg, PKCS1v15); + assert(msg == dmsg); + } + #[test] fn test_sign() { let k0 = PKey(); From 3ef8dc772b1e031f2926ddd873e746f8de88324f Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 20:01:03 +0100 Subject: [PATCH 02/23] Add support for RSA signing with alternate hashes (MD5, SHA-512, etc) --- pkey.rs | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file 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); + } + } From d4363841691dba0af5b1b411376d8fc344f96ad7 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 20:04:26 +0100 Subject: [PATCH 03/23] Update readme with new hash/padding options --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 774949f7..82a1c526 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ libcrypto. Currently provided: * Keypair generation (pkey.rs) * RSA, all key lengths * Asymmetric encryption (pkey.rs) - * RSA with PKCS#1 OAEP padding + * RSA with PKCS #1 OAEP padding or PKCS #1 v1.5 padding * Digital signatures (pkey.rs) - * RSA with whatever your system openssl does (PKCS#1 on my system) and sha256 + * RSA with PKCS #1 v1.5 padding and any supported hash Each module provides two interfaces: a low-level API which wraps the OpenSSL interfaces as directly as possible and a high-level API which presents the From 07773d8fee23ab31ac1fed917ddcc102f07aa9db Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 20:44:16 +0100 Subject: [PATCH 04/23] Add support for HMAC, RC4, AES-128, hex encoding, etc --- Makefile | 7 +++++ hex.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hmac.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 Makefile create mode 100644 hex.rs create mode 100644 hmac.rs diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..2d55d237 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ + +crypto: crypto.rc $(wildcard *.rs) + rustc crypto.rc + rustc --test crypto.rc + +clean: + rm -f crypto libcrypto-*.so diff --git a/hex.rs b/hex.rs new file mode 100644 index 00000000..ca422a49 --- /dev/null +++ b/hex.rs @@ -0,0 +1,91 @@ +/* + * Copyright 2013 Jack Lloyd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +extern mod std; + +pub trait ToHex { + pure fn to_hex() -> ~str; +} + +impl &[u8]: ToHex { + pure fn to_hex() -> ~str { + + let chars = str::chars(~"0123456789ABCDEF"); + + let mut s = ~""; + + for uint::range(0, self.len()) |i| { + + let x = self[i]; + + let xhi = (x >> 4) & 0x0F; + let xlo = (x ) & 0x0F; + + unsafe { + str::push_char(&mut s, chars[xhi]); + str::push_char(&mut s, chars[xlo]); + } + } + + s + } +} + +pub trait FromHex { + pure fn from_hex() -> ~[u8]; +} + +impl &str: FromHex { + pure fn from_hex() -> ~[u8] { + let mut vec = vec::with_capacity(self.len() / 2); + + for str::each_chari(self) |i,c| { + + let nibble = + if c >= '0' && c <= '9' { (c as u8) - 0x30 } + else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } + else if c >= 'A' && c <= 'F' { (c as u8) - (0x41 - 10) } + else { fail ~"bad hex character"; }; + + if i % 2 == 0 { + unsafe { + vec::push(&mut vec, nibble << 4); + } + } + else { + vec[i/2] |= nibble; + } + } + + vec + } +} + +#[cfg(test)] +mod tests { + + #[test] + pub fn test() { + + assert [05u8, 0xffu8, 0x00u8, 0x59u8].to_hex() == ~"05FF0059"; + + assert "00FFA9D1F5".from_hex() == ~[0, 0xff, 0xa9, 0xd1, 0xf5]; + + assert "00FFA9D1F5".from_hex().to_hex() == ~"00FFA9D1F5"; + } + + +} \ No newline at end of file diff --git a/hmac.rs b/hmac.rs new file mode 100644 index 00000000..1dc40344 --- /dev/null +++ b/hmac.rs @@ -0,0 +1,92 @@ +/* + * Copyright 2013 Jack Lloyd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use hash::*; + +#[allow(non_camel_case_types)] +struct HMAC_CTX { + mut md: EVP_MD, + mut md_ctx: EVP_MD_CTX, + mut i_ctx: EVP_MD_CTX, + mut o_ctx: EVP_MD_CTX, + mut key_length: libc::c_uint, + mut key: [libc::c_uchar * 128] +} + +#[link_name = "crypto"] +#[abi = "cdecl"] +extern mod libcrypto { + + fn HMAC_CTX_init(ctx: *mut HMAC_CTX, key: *u8, keylen: libc::c_int, md: EVP_MD); + + fn HMAC_Update(ctx: *mut HMAC_CTX, input: *u8, len: libc::c_uint); + + fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut libc::c_uint); +} + +pub struct HMAC { + priv mut ctx: HMAC_CTX, + priv len: uint, +} + +pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { + unsafe { + + let (evp, mdlen) = evpmd(ht); + + let mut ctx : HMAC_CTX = HMAC_CTX { + mut md: ptr::null(), + mut md_ctx: ptr::null(), + mut i_ctx: ptr::null(), + mut o_ctx: ptr::null(), + mut key_length: 0, + mut key: [0u8, .. 128] + }; + + libcrypto::HMAC_CTX_init(&mut ctx, + vec::raw::to_ptr(key), + key.len() as libc::c_int, + evp); + + HMAC { ctx: ctx, len: mdlen } + } +} + +pub impl HMAC { + fn update(data: &[u8]) unsafe { + do vec::as_imm_buf(data) |pdata, len| { + libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) + } + } + + fn final() -> ~[u8] unsafe { + let mut res = vec::from_elem(self.len, 0u8); + let mut outlen: libc::c_uint = 0; + do vec::as_mut_buf(res) |pres, _len| { + libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); + assert self.len == outlen as uint + } + res + } +} + +fn main() { + let h = HMAC(SHA512, ~[00u8]); + + h.update(~[00u8]); + + io::println(fmt!("%?", h.final())) +} From f8512d7d5e17d2a59cfdd18dff0817d75e4b4c92 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 20:49:04 +0100 Subject: [PATCH 05/23] Add RC4 and AES-128 support to Cryptor --- .gitignore | 1 + README.md | 3 ++- crypto.rc | 9 ++++++--- rand.rs | 3 ++- symm.rs | 36 ++++++++++++++++++++++++++++++++++-- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index cd49243d..ecfc5572 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.sw[po] libcrypto*.dylib +libcrypto*.so *.dSYM/ crypto diff --git a/README.md b/README.md index 82a1c526..4554176d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ libcrypto. Currently provided: * SHA-1 * SHA-2 (224, 256, 384, 512) * Symmetric crypto (symm.rs) - * AES in ECB or CBC mode, all key lengths + * AES-128 or AES-256 in ECB or CBC mode + * RC4-128 * Keypair generation (pkey.rs) * RSA, all key lengths * Asymmetric encryption (pkey.rs) diff --git a/crypto.rc b/crypto.rc index 0f33533f..eeccd14f 100644 --- a/crypto.rc +++ b/crypto.rc @@ -1,5 +1,6 @@ /* * Copyright 2011 Google Inc. + * 2013 Jack Lloyd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +16,16 @@ */ #[link(name = "crypto", - vers = "0.2", + vers = "0.3", uuid = "38297409-b4c2-4499-8131-a99a7e44dad3")]; #[crate_type = "lib"]; extern mod std; // FIXME https://github.com/mozilla/rust/issues/1127 +pub mod hex; pub mod hash; -pub mod pkey; -pub mod symm; +pub mod hmac; pub mod pkcs5; +pub mod pkey; pub mod rand; +pub mod symm; diff --git a/rand.rs b/rand.rs index c6e0c4a0..72acdd19 100644 --- a/rand.rs +++ b/rand.rs @@ -23,6 +23,7 @@ pub fn rand_bytes(len: uint) -> ~[u8] { mod tests { #[test] fn test_rand_bytes() { - let _bytes = rand_bytes(5u); + let bytes = rand_bytes(32u); + io::println(fmt!("%?", bytes)); } } diff --git a/symm.rs b/symm.rs index b0b92638..030802f6 100644 --- a/symm.rs +++ b/symm.rs @@ -23,6 +23,8 @@ extern mod libcrypto { fn EVP_aes_256_ecb() -> EVP_CIPHER; fn EVP_aes_256_cbc() -> EVP_CIPHER; + fn EVP_rc4() -> EVP_CIPHER; + fn EVP_CipherInit(ctx: EVP_CIPHER_CTX, evp: EVP_CIPHER, key: *u8, iv: *u8, mode: c_int); fn EVP_CipherUpdate(ctx: EVP_CIPHER_CTX, outbuf: *mut u8, @@ -37,14 +39,24 @@ pub enum Mode { #[allow(non_camel_case_types)] pub enum Type { + AES_128_ECB, + AES_128_CBC, + AES_256_ECB, AES_256_CBC, + + RC4_128, } fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { match t { + AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), + AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), + AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), + + RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), } } @@ -68,8 +80,10 @@ pub impl Crypter { * data encrypted must be a multiple of block size. */ fn pad(padding: bool) { - let v = if padding { 1 } else { 0} as c_int; - libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + if self.blocksize > 0 { + let v = if padding { 1 } else { 0 } as c_int; + libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + } } /** @@ -188,4 +202,22 @@ mod tests { let p1 = c.update(r0) + c.final(); assert(p1 == p0); } + + #[test] + pub fn test_rc4() { + use hex::FromHex; + + let pt = ~"0000000000000000000000000000000000000000000000000000000000000000000000000000"; + let ct = ~"A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; + let key = ~"97CD440324DA5FD1F7955C1C13B6B466"; + let iv = ~""; + + let cipher = Crypter(RC4_128); + cipher.init(Encrypt, key.from_hex(), iv.from_hex()); + + let computed = cipher.update(pt.from_hex()); + + assert computed == ct.from_hex(); + } + } From b53582ab969c56c13fa20e8f5d715afd79225ab6 Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 11 Mar 2013 21:40:23 +0100 Subject: [PATCH 06/23] Take hash test inputs as hex strings. Add MD5 tests. --- hash.rs | 77 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/hash.rs b/hash.rs index 6e0af07a..da235ae3 100644 --- a/hash.rs +++ b/hash.rs @@ -95,34 +95,75 @@ pub fn hash(t: HashType, data: &[u8]) -> ~[u8] unsafe { #[cfg(test)] mod tests { + use hex::FromHex; + use hex::ToHex; + + struct HashTest { + input: ~[u8], + expected_output: ~str + } + + fn HashTest(input: ~str, output: ~str) -> HashTest { + HashTest { input: input.from_hex(), + expected_output: output } + } + + fn hash_test(hashtype: HashType, hashtest: &HashTest) { + let calced_raw = hash(hashtype, hashtest.input); + + let calced = calced_raw.to_hex(); + + if calced != hashtest.expected_output { + io::println(fmt!("Test failed - %s != %s", calced, hashtest.expected_output)); + } + + assert calced == hashtest.expected_output; + } + // Test vectors from http://www.nsrl.nist.gov/testdata/ #[test] fn test_md5() { - let s0 = ~[0x61u8, 0x62u8, 0x63u8]; - let d0 = - ~[0x90u8, 0x01u8, 0x50u8, 0x98u8, 0x3cu8, 0xd2u8, 0x4fu8, 0xb0u8, - 0xd6u8, 0x96u8, 0x3fu8, 0x7du8, 0x28u8, 0xe1u8, 0x7fu8, 0x72u8]; - assert(hash(MD5, s0) == d0); + + let tests = [ + HashTest(~"", ~"D41D8CD98F00B204E9800998ECF8427E"), + HashTest(~"7F", ~"83ACB6E67E50E31DB6ED341DD2DE1595"), + HashTest(~"EC9C", ~"0B07F0D4CA797D8AC58874F887CB0B68"), + HashTest(~"FEE57A", ~"E0D583171EB06D56198FC0EF22173907"), + HashTest(~"42F497E0", ~"7C430F178AEFDF1487FEE7144E9641E2"), + HashTest(~"C53B777F1C", ~"75EF141D64CB37EC423DA2D9D440C925"), + HashTest(~"89D5B576327B", ~"EBBAF15EB0ED784C6FAA9DC32831BF33"), + HashTest(~"5D4CCE781EB190", ~"CE175C4B08172019F05E6B5279889F2C"), + HashTest(~"81901FE94932D7B9", ~"CD4D2F62B8CDB3A0CF968A735A239281"), + HashTest(~"C9FFDEE7788EFB4EC9", ~"E0841A231AB698DB30C6C0F3F246C014"), + HashTest(~"66AC4B7EBA95E53DC10B", ~"A3B3CEA71910D9AF56742AA0BB2FE329"), + HashTest(~"A510CD18F7A56852EB0319", ~"577E216843DD11573574D3FB209B97D8"), + HashTest(~"AAED18DBE8938C19ED734A8D", ~"6F80FB775F27E0A4CE5C2F42FC72C5F1")]; + + for vec::each(tests) |test| { + hash_test(MD5, test); + } } #[test] fn test_sha1() { - let s0 = ~[0x61u8, 0x62u8, 0x63u8]; - let d0 = - ~[0xa9u8, 0x99u8, 0x3eu8, 0x36u8, 0x47u8, 0x06u8, 0x81u8, 0x6au8, - 0xbau8, 0x3eu8, 0x25u8, 0x71u8, 0x78u8, 0x50u8, 0xc2u8, 0x6cu8, - 0x9cu8, 0xd0u8, 0xd8u8, 0x9du8]; - assert(hash(SHA1, s0) == d0); + + let tests = [ + HashTest(~"616263", ~"A9993E364706816ABA3E25717850C26C9CD0D89D"), + ]; + + for vec::each(tests) |test| { + hash_test(SHA1, test); + } } #[test] fn test_sha256() { - let s0 = ~[0x61u8, 0x62u8, 0x63u8]; - let d0 = - ~[0xbau8, 0x78u8, 0x16u8, 0xbfu8, 0x8fu8, 0x01u8, 0xcfu8, 0xeau8, - 0x41u8, 0x41u8, 0x40u8, 0xdeu8, 0x5du8, 0xaeu8, 0x22u8, 0x23u8, - 0xb0u8, 0x03u8, 0x61u8, 0xa3u8, 0x96u8, 0x17u8, 0x7au8, 0x9cu8, - 0xb4u8, 0x10u8, 0xffu8, 0x61u8, 0xf2u8, 0x00u8, 0x15u8, 0xadu8]; - assert(hash(SHA256, s0) == d0); + let tests = [ + HashTest(~"616263", ~"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD") + ]; + + for vec::each(tests) |test| { + hash_test(SHA256, test); + } } } From fb9cce31fb5c53dd3f3f9c853d2e110c87c3834d Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 12 Mar 2013 19:34:14 +0100 Subject: [PATCH 07/23] Add CTR and GCM support --- README.md | 25 ++++++++----------------- symm.rs | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 4554176d..16740d5b 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,13 @@ This package provides Rust bindings for the functionality exposed by OpenSSL's -libcrypto. Currently provided: +libcrypto. OpenSSL 1.0.1 or higher is required. Currently provided: -* Hashes (hash.rs) - * MD5 +* Hash functions (hash.rs) + * SHA-512, SHA-384, SHA-256, SHA-224 * SHA-1 - * SHA-2 (224, 256, 384, 512) + * MD5 * Symmetric crypto (symm.rs) - * AES-128 or AES-256 in ECB or CBC mode + * AES-128 and AES-256 (ECB, CBC, CTR or GCM mode) * RC4-128 -* Keypair generation (pkey.rs) - * RSA, all key lengths -* Asymmetric encryption (pkey.rs) - * RSA with PKCS #1 OAEP padding or PKCS #1 v1.5 padding -* Digital signatures (pkey.rs) - * RSA with PKCS #1 v1.5 padding and any supported hash - -Each module provides two interfaces: a low-level API which wraps the OpenSSL -interfaces as directly as possible and a high-level API which presents the -OpenSSL API as a Rust object and tries to make sensible default choices about -parameters most users won't care about. You probably want to use the high-level -API. For documentation on these, see the individual source files. +* RSA (pkey.rs) + * Encryption with PKCS #1 OAEP padding or PKCS #1 v1.5 padding + * Signatures with PKCS #1 v1.5 padding and any supported hash diff --git a/symm.rs b/symm.rs index 030802f6..57b096bb 100644 --- a/symm.rs +++ b/symm.rs @@ -18,10 +18,13 @@ extern mod libcrypto { fn EVP_aes_128_ecb() -> EVP_CIPHER; fn EVP_aes_128_cbc() -> EVP_CIPHER; - fn EVP_aes_192_ecb() -> EVP_CIPHER; - fn EVP_aes_192_cbc() -> EVP_CIPHER; + fn EVP_aes_128_ctr() -> EVP_CIPHER; + fn EVP_aes_128_gcm() -> EVP_CIPHER; + fn EVP_aes_256_ecb() -> EVP_CIPHER; fn EVP_aes_256_cbc() -> EVP_CIPHER; + fn EVP_aes_256_ctr() -> EVP_CIPHER; + fn EVP_aes_256_gcm() -> EVP_CIPHER; fn EVP_rc4() -> EVP_CIPHER; @@ -41,9 +44,13 @@ pub enum Mode { pub enum Type { AES_128_ECB, AES_128_CBC, + AES_128_CTR, + AES_128_GCM, AES_256_ECB, AES_256_CBC, + AES_256_CTR, + AES_256_GCM, RC4_128, } @@ -52,9 +59,13 @@ fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { match t { AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), + AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 16u), + AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), + AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 16u), + AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), } @@ -177,6 +188,8 @@ fn decrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { #[cfg(test)] mod tests { + use hex::FromHex; + // Test vectors from FIPS-197: // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf #[test] @@ -203,16 +216,8 @@ mod tests { assert(p1 == p0); } - #[test] - pub fn test_rc4() { - use hex::FromHex; - - let pt = ~"0000000000000000000000000000000000000000000000000000000000000000000000000000"; - let ct = ~"A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; - let key = ~"97CD440324DA5FD1F7955C1C13B6B466"; - let iv = ~""; - - let cipher = Crypter(RC4_128); + fn cipher_test(ciphertype: Type, pt: ~str, ct: ~str, key: ~str, iv: ~str) { + let cipher = Crypter(ciphertype); cipher.init(Encrypt, key.from_hex(), iv.from_hex()); let computed = cipher.update(pt.from_hex()); @@ -220,4 +225,15 @@ mod tests { assert computed == ct.from_hex(); } + #[test] + fn test_rc4() { + + let pt = ~"0000000000000000000000000000000000000000000000000000000000000000000000000000"; + let ct = ~"A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; + let key = ~"97CD440324DA5FD1F7955C1C13B6B466"; + let iv = ~""; + + cipher_test(RC4_128, pt, ct, key, iv); + } + } From 1cb2f63ad4006143371087e07260cd35c9e5ff0d Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 12 Mar 2013 20:03:05 +0100 Subject: [PATCH 08/23] Remove GCM support for now, EVP is more complicated than that --- symm.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/symm.rs b/symm.rs index 57b096bb..8c036333 100644 --- a/symm.rs +++ b/symm.rs @@ -45,12 +45,12 @@ pub enum Type { AES_128_ECB, AES_128_CBC, AES_128_CTR, - AES_128_GCM, + //AES_128_GCM, AES_256_ECB, AES_256_CBC, AES_256_CTR, - AES_256_GCM, + //AES_256_GCM, RC4_128, } @@ -59,13 +59,13 @@ fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { match t { AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), - AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 16u), - AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), + AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 0u), + //AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), - AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 16u), - AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), + AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 0u), + //AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), } @@ -152,12 +152,16 @@ pub impl Crypter { fn final() -> ~[u8] unsafe { let res = vec::to_mut(vec::from_elem(self.blocksize, 0u8)); + io::println(fmt!("final, res %? long", res.len())); + let reslen = do vec::as_mut_buf(res) |pres, _len| { let mut reslen = self.blocksize as c_int; libcrypto::EVP_CipherFinal(self.ctx, pres, &mut reslen); reslen }; + io::println(fmt!("openssl says %? bytes", reslen)); + vec::slice(res, 0u, reslen as uint) } } @@ -217,12 +221,23 @@ mod tests { } fn cipher_test(ciphertype: Type, pt: ~str, ct: ~str, key: ~str, iv: ~str) { + use hex::ToHex; + let cipher = Crypter(ciphertype); cipher.init(Encrypt, key.from_hex(), iv.from_hex()); - let computed = cipher.update(pt.from_hex()); + let expected = ct.from_hex(); + let computed = cipher.update(pt.from_hex()) + cipher.final(); - assert computed == ct.from_hex(); + if computed != expected { + io::println(fmt!("Computed: %s", computed.to_hex())); + io::println(fmt!("Expected: %s", expected.to_hex())); + if computed.len() != expected.len() { + io::println(fmt!("Lengths differ: %u in computed vs %u expected", + computed.len(), expected.len())); + } + fail ~"test failure"; + } } #[test] @@ -236,4 +251,26 @@ mod tests { cipher_test(RC4_128, pt, ct, key, iv); } + #[test] + fn test_aes128_ctr() { + + let pt = ~"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"; + let ct = ~"874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE"; + let key = ~"2B7E151628AED2A6ABF7158809CF4F3C"; + let iv = ~"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"; + + cipher_test(AES_128_CTR, pt, ct, key, iv); + } + + #[test] + fn test_aes128_gcm() { + // Test case 3 in GCM spec + let pt = ~"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"; + let ct = ~"42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4"; + let key = ~"feffe9928665731c6d6a8f9467308308"; + let iv = ~"cafebabefacedbaddecaf888"; + + cipher_test(AES_128_GCM, pt, ct, key, iv); + } + } From 9d09a98664624dc360e5411832507fb874891e7e Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 20 Apr 2013 01:12:03 -0700 Subject: [PATCH 09/23] Update for Rust 0.6 Also disable AES_128_CTR and AES_256_CTR because they cause link failures on OS X. --- hash.rs | 75 ++++++----- hex.rs | 25 ++-- hmac.rs | 42 ++++--- pkcs5.rs | 46 +++---- pkey.rs | 378 ++++++++++++++++++++++++++++++------------------------- rand.rs | 10 +- symm.rs | 162 +++++++++++++----------- 7 files changed, 405 insertions(+), 333 deletions(-) diff --git a/hash.rs b/hash.rs index da235ae3..14b39aa4 100644 --- a/hash.rs +++ b/hash.rs @@ -1,4 +1,4 @@ -use libc::c_uint; +use core::libc::c_uint; pub enum HashType { MD5, @@ -10,10 +10,10 @@ pub enum HashType { } #[allow(non_camel_case_types)] -type EVP_MD_CTX = *libc::c_void; +pub type EVP_MD_CTX = *libc::c_void; #[allow(non_camel_case_types)] -type EVP_MD = *libc::c_void; +pub type EVP_MD = *libc::c_void; #[link_name = "crypto"] #[abi = "cdecl"] @@ -32,14 +32,16 @@ extern mod libcrypto { fn EVP_DigestFinal(ctx: EVP_MD_CTX, res: *mut u8, n: *u32); } -fn evpmd(t: HashType) -> (EVP_MD, uint) { - match t { - 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), +pub fn evpmd(t: HashType) -> (EVP_MD, uint) { + unsafe { + match t { + 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), + } } } @@ -50,23 +52,29 @@ pub struct Hasher { } pub fn Hasher(ht: HashType) -> Hasher { - let ctx = libcrypto::EVP_MD_CTX_create(); - let (evp, mdlen) = evpmd(ht); - let h = Hasher { evp: evp, ctx: ctx, len: mdlen }; - h.init(); - h + unsafe { + let ctx = libcrypto::EVP_MD_CTX_create(); + let (evp, mdlen) = evpmd(ht); + let h = Hasher { evp: evp, ctx: ctx, len: mdlen }; + h.init(); + h + } } pub impl Hasher { /// Initializes this hasher - fn init() unsafe { - libcrypto::EVP_DigestInit(self.ctx, self.evp); + fn init(&self) { + unsafe { + libcrypto::EVP_DigestInit(self.ctx, self.evp); + } } /// Update this hasher with more input bytes - fn update(data: &[u8]) unsafe { - do vec::as_imm_buf(data) |pdata, len| { - libcrypto::EVP_DigestUpdate(self.ctx, pdata, len as c_uint) + fn update(&self, data: &[u8]) { + unsafe { + do vec::as_imm_buf(data) |pdata, len| { + libcrypto::EVP_DigestUpdate(self.ctx, pdata, len as c_uint) + } } } @@ -74,12 +82,14 @@ pub impl Hasher { * Return the digest of all bytes added to this hasher since its last * initialization */ - fn final() -> ~[u8] unsafe { - let mut res = vec::from_elem(self.len, 0u8); - do vec::as_mut_buf(res) |pres, _len| { - libcrypto::EVP_DigestFinal(self.ctx, pres, ptr::null()); + fn final(&self) -> ~[u8] { + unsafe { + let mut res = vec::from_elem(self.len, 0u8); + do vec::as_mut_buf(res) |pres, _len| { + libcrypto::EVP_DigestFinal(self.ctx, pres, ptr::null()); + } + res } - res } } @@ -87,14 +97,17 @@ pub impl Hasher { * Hashes the supplied input data using hash t, returning the resulting hash * value */ -pub fn hash(t: HashType, data: &[u8]) -> ~[u8] unsafe { - let h = Hasher(t); - h.update(data); - h.final() +pub fn hash(t: HashType, data: &[u8]) -> ~[u8] { + unsafe { + let h = Hasher(t); + h.update(data); + h.final() + } } #[cfg(test)] mod tests { + use super::*; use hex::FromHex; use hex::ToHex; @@ -117,7 +130,7 @@ mod tests { io::println(fmt!("Test failed - %s != %s", calced, hashtest.expected_output)); } - assert calced == hashtest.expected_output; + assert!(calced == hashtest.expected_output); } // Test vectors from http://www.nsrl.nist.gov/testdata/ diff --git a/hex.rs b/hex.rs index ca422a49..2193e49c 100644 --- a/hex.rs +++ b/hex.rs @@ -17,13 +17,13 @@ extern mod std; pub trait ToHex { - pure fn to_hex() -> ~str; + fn to_hex(&self) -> ~str; } -impl &[u8]: ToHex { - pure fn to_hex() -> ~str { +impl<'self> ToHex for &'self [u8] { + fn to_hex(&self) -> ~str { - let chars = str::chars(~"0123456789ABCDEF"); + let chars = str::to_chars(~"0123456789ABCDEF"); let mut s = ~""; @@ -45,20 +45,20 @@ impl &[u8]: ToHex { } pub trait FromHex { - pure fn from_hex() -> ~[u8]; + fn from_hex(&self) -> ~[u8]; } -impl &str: FromHex { - pure fn from_hex() -> ~[u8] { +impl<'self> FromHex for &'self str { + fn from_hex(&self) -> ~[u8] { let mut vec = vec::with_capacity(self.len() / 2); - for str::each_chari(self) |i,c| { + for str::each_chari(*self) |i,c| { let nibble = if c >= '0' && c <= '9' { (c as u8) - 0x30 } else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } else if c >= 'A' && c <= 'F' { (c as u8) - (0x41 - 10) } - else { fail ~"bad hex character"; }; + else { fail!(~"bad hex character"); }; if i % 2 == 0 { unsafe { @@ -76,15 +76,16 @@ impl &str: FromHex { #[cfg(test)] mod tests { + use super::*; #[test] pub fn test() { - assert [05u8, 0xffu8, 0x00u8, 0x59u8].to_hex() == ~"05FF0059"; + assert!([05u8, 0xffu8, 0x00u8, 0x59u8].to_hex() == ~"05FF0059"); - assert "00FFA9D1F5".from_hex() == ~[0, 0xff, 0xa9, 0xd1, 0xf5]; + assert!("00FFA9D1F5".from_hex() == ~[0, 0xff, 0xa9, 0xd1, 0xf5]); - assert "00FFA9D1F5".from_hex().to_hex() == ~"00FFA9D1F5"; + assert!("00FFA9D1F5".from_hex().to_hex() == ~"00FFA9D1F5"); } diff --git a/hmac.rs b/hmac.rs index 1dc40344..dd35010f 100644 --- a/hmac.rs +++ b/hmac.rs @@ -17,13 +17,13 @@ use hash::*; #[allow(non_camel_case_types)] -struct HMAC_CTX { - mut md: EVP_MD, - mut md_ctx: EVP_MD_CTX, - mut i_ctx: EVP_MD_CTX, - mut o_ctx: EVP_MD_CTX, - mut key_length: libc::c_uint, - mut key: [libc::c_uchar * 128] +pub struct HMAC_CTX { + md: EVP_MD, + md_ctx: EVP_MD_CTX, + i_ctx: EVP_MD_CTX, + o_ctx: EVP_MD_CTX, + key_length: libc::c_uint, + key: [libc::c_uchar, ..128] } #[link_name = "crypto"] @@ -38,7 +38,7 @@ extern mod libcrypto { } pub struct HMAC { - priv mut ctx: HMAC_CTX, + priv ctx: HMAC_CTX, priv len: uint, } @@ -66,25 +66,29 @@ pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { } pub impl HMAC { - fn update(data: &[u8]) unsafe { - do vec::as_imm_buf(data) |pdata, len| { - libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) + fn update(&mut self, data: &[u8]) { + unsafe { + do vec::as_imm_buf(data) |pdata, len| { + libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) + } } } - fn final() -> ~[u8] unsafe { - let mut res = vec::from_elem(self.len, 0u8); - let mut outlen: libc::c_uint = 0; - do vec::as_mut_buf(res) |pres, _len| { - libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); - assert self.len == outlen as uint + fn final(&mut self) -> ~[u8] { + unsafe { + let mut res = vec::from_elem(self.len, 0u8); + let mut outlen: libc::c_uint = 0; + do vec::as_mut_buf(res) |pres, _len| { + libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); + assert!(self.len == outlen as uint) + } + res } - res } } fn main() { - let h = HMAC(SHA512, ~[00u8]); + let mut h = HMAC(SHA512, ~[00u8]); h.update(~[00u8]); diff --git a/pkcs5.rs b/pkcs5.rs index 8ce32c54..ec81c333 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -1,4 +1,4 @@ -use libc::{c_char, c_uchar, c_int}; +use core::libc::c_int; #[link_name = "crypto"] #[abi = "cdecl"] @@ -14,21 +14,23 @@ Derives a key from a password and salt using the PBKDF2-HMAC-SHA1 algorithm. "] pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, keylen: uint) -> ~[u8] { - assert iter >= 1u; - assert keylen >= 1u; + assert!(iter >= 1u); + assert!(keylen >= 1u); do str::as_buf(pass) |pass_buf, pass_len| { do vec::as_imm_buf(salt) |salt_buf, salt_len| { let mut out = vec::with_capacity(keylen); do vec::as_mut_buf(out) |out_buf, _out_len| { - let r = libcrypto::PKCS5_PBKDF2_HMAC_SHA1( - pass_buf, pass_len as c_int, - salt_buf, salt_len as c_int, - iter as c_int, keylen as c_int, - out_buf); + unsafe { + let r = libcrypto::PKCS5_PBKDF2_HMAC_SHA1( + pass_buf, pass_len as c_int, + salt_buf, salt_len as c_int, + iter as c_int, keylen as c_int, + out_buf); - if r != 1 as c_int { fail; } + if r != 1 as c_int { fail!(); } + } } unsafe { vec::raw::set_len(&mut out, keylen); } @@ -40,11 +42,13 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, #[cfg(test)] mod tests { + use super::*; + // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 #[test] fn test_pbkdf2_hmac_sha1() { - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "password", str::to_bytes("salt"), 1u, @@ -53,9 +57,9 @@ mod tests { 0x0c_u8, 0x60_u8, 0xc8_u8, 0x0f_u8, 0x96_u8, 0x1f_u8, 0x0e_u8, 0x71_u8, 0xf3_u8, 0xa9_u8, 0xb5_u8, 0x24_u8, 0xaf_u8, 0x60_u8, 0x12_u8, 0x06_u8, 0x2f_u8, 0xe0_u8, 0x37_u8, 0xa6_u8 - ]; + ]); - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "password", str::to_bytes("salt"), 2u, @@ -64,9 +68,9 @@ mod tests { 0xea_u8, 0x6c_u8, 0x01_u8, 0x4d_u8, 0xc7_u8, 0x2d_u8, 0x6f_u8, 0x8c_u8, 0xcd_u8, 0x1e_u8, 0xd9_u8, 0x2a_u8, 0xce_u8, 0x1d_u8, 0x41_u8, 0xf0_u8, 0xd8_u8, 0xde_u8, 0x89_u8, 0x57_u8 - ]; + ]); - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "password", str::to_bytes("salt"), 4096u, @@ -75,9 +79,9 @@ mod tests { 0x4b_u8, 0x00_u8, 0x79_u8, 0x01_u8, 0xb7_u8, 0x65_u8, 0x48_u8, 0x9a_u8, 0xbe_u8, 0xad_u8, 0x49_u8, 0xd9_u8, 0x26_u8, 0xf7_u8, 0x21_u8, 0xd0_u8, 0x65_u8, 0xa4_u8, 0x29_u8, 0xc1_u8 - ]; + ]); - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "password", str::to_bytes("salt"), 16777216u, @@ -86,9 +90,9 @@ mod tests { 0xee_u8, 0xfe_u8, 0x3d_u8, 0x61_u8, 0xcd_u8, 0x4d_u8, 0xa4_u8, 0xe4_u8, 0xe9_u8, 0x94_u8, 0x5b_u8, 0x3d_u8, 0x6b_u8, 0xa2_u8, 0x15_u8, 0x8c_u8, 0x26_u8, 0x34_u8, 0xe9_u8, 0x84_u8 - ]; + ]); - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "passwordPASSWORDpassword", str::to_bytes("saltSALTsaltSALTsaltSALTsaltSALTsalt"), 4096u, @@ -98,9 +102,9 @@ mod tests { 0x9b_u8, 0x80_u8, 0xc8_u8, 0xd8_u8, 0x36_u8, 0x62_u8, 0xc0_u8, 0xe4_u8, 0x4a_u8, 0x8b_u8, 0x29_u8, 0x1a_u8, 0x96_u8, 0x4c_u8, 0xf2_u8, 0xf0_u8, 0x70_u8, 0x38_u8 - ]; + ]); - assert pbkdf2_hmac_sha1( + assert!(pbkdf2_hmac_sha1( "pass\x00word", str::to_bytes("sa\x00lt"), 4096u, @@ -109,6 +113,6 @@ mod tests { 0x56_u8, 0xfa_u8, 0x6a_u8, 0xa7_u8, 0x55_u8, 0x48_u8, 0x09_u8, 0x9d_u8, 0xcc_u8, 0x37_u8, 0xd7_u8, 0xf0_u8, 0x34_u8, 0x25_u8, 0xe0_u8, 0xc3_u8 - ]; + ]); } } diff --git a/pkey.rs b/pkey.rs index 2d253eca..a3533778 100644 --- a/pkey.rs +++ b/pkey.rs @@ -1,4 +1,4 @@ -use libc::{c_int, c_uint}; +use core::libc::{c_int, c_uint}; use hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512}; #[allow(non_camel_case_types)] @@ -74,107 +74,130 @@ fn openssl_hash_nid(hash: HashType) -> c_int { } } -fn rsa_to_any(rsa: *RSA) -> *ANYKEY unsafe { - cast::reinterpret_cast(&rsa) +fn rsa_to_any(rsa: *RSA) -> *ANYKEY { + unsafe { + cast::reinterpret_cast(&rsa) + } } -fn any_to_rsa(anykey: *ANYKEY) -> *RSA unsafe { - cast::reinterpret_cast(&anykey) +fn any_to_rsa(anykey: *ANYKEY) -> *RSA { + unsafe { + cast::reinterpret_cast(&anykey) + } } pub struct PKey { - priv mut evp: *EVP_PKEY, - priv mut parts: Parts, + priv evp: *EVP_PKEY, + priv parts: Parts, } pub fn PKey() -> PKey { - PKey { evp: libcrypto::EVP_PKEY_new(), parts: Neither } -} - -priv impl PKey { - fn _tostr(f: fn@(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] unsafe { - let buf = ptr::mut_null(); - let len = f(self.evp, &buf); - if len < 0 as c_int { return ~[]; } - let mut s = vec::from_elem(len as uint, 0u8); - - let r = do vec::as_mut_buf(s) |ps, _len| { - f(self.evp, &ps) - }; - - vec::slice(s, 0u, r as uint) - } - - fn _fromstr( - s: &[u8], - f: fn@(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY - ) unsafe { - do vec::as_imm_buf(s) |ps, len| { - let evp = ptr::null(); - f(6 as c_int, &evp, &ps, len as c_uint); - self.evp = evp; - } + unsafe { + PKey { evp: libcrypto::EVP_PKEY_new(), parts: Neither } } } ///Represents a public key, optionally with a private key attached. -pub impl PKey { - fn gen(keysz: uint) unsafe { - let rsa = libcrypto::RSA_generate_key( - keysz as c_uint, - 65537u as c_uint, - ptr::null(), - ptr::null() - ); +priv impl PKey { + priv fn _tostr(&self, f: @fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { + unsafe { + let buf = ptr::mut_null(); + let len = f(self.evp, &buf); + if len < 0 as c_int { return ~[]; } + let mut s = vec::from_elem(len as uint, 0u8); - let rsa_ = rsa_to_any(rsa); - // XXX: 6 == NID_rsaEncryption - libcrypto::EVP_PKEY_assign(self.evp, 6 as c_int, rsa_); - self.parts = Both; + let r = do vec::as_mut_buf(s) |ps, _len| { + f(self.evp, &ps) + }; + + vec::slice(s, 0u, r as uint).to_owned() + } + } + + priv fn _fromstr( + &mut self, + s: &[u8], + f: @fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY + ) { + unsafe { + do vec::as_imm_buf(s) |ps, len| { + let evp = ptr::null(); + f(6 as c_int, &evp, &ps, len as c_uint); + self.evp = evp; + } + } + } +} + +pub impl PKey { + fn gen(&mut self, keysz: uint) { + unsafe { + let rsa = libcrypto::RSA_generate_key( + keysz as c_uint, + 65537u as c_uint, + ptr::null(), + ptr::null() + ); + + let rsa_ = rsa_to_any(rsa); + // XXX: 6 == NID_rsaEncryption + libcrypto::EVP_PKEY_assign(self.evp, 6 as c_int, rsa_); + self.parts = Both; + } } /** * Returns a serialized form of the public key, suitable for load_pub(). */ - fn save_pub() -> ~[u8] { - self._tostr(libcrypto::i2d_PublicKey) + fn save_pub(&self) -> ~[u8] { + unsafe { + self._tostr(libcrypto::i2d_PublicKey) + } } /** * Loads a serialized form of the public key, as produced by save_pub(). */ - fn load_pub(s: &[u8]) { - self._fromstr(s, libcrypto::d2i_PublicKey); - self.parts = Public; + fn load_pub(&mut self, s: &[u8]) { + unsafe { + self._fromstr(s, libcrypto::d2i_PublicKey); + self.parts = Public; + } } /** * Returns a serialized form of the public and private keys, suitable for * load_priv(). */ - fn save_priv() -> ~[u8] { - self._tostr(libcrypto::i2d_PrivateKey) + fn save_priv(&self, ) -> ~[u8] { + unsafe { + self._tostr(libcrypto::i2d_PrivateKey) + } } /** * Loads a serialized form of the public and private keys, as produced by * save_priv(). */ - fn load_priv(s: &[u8]) { - self._fromstr(s, libcrypto::d2i_PrivateKey); - self.parts = Both; + fn load_priv(&mut self, s: &[u8]) { + unsafe { + self._fromstr(s, libcrypto::d2i_PrivateKey); + self.parts = Both; + } } /** * Returns the size of the public key modulus. */ - fn size() -> uint { - libcrypto::RSA_size(libcrypto::EVP_PKEY_get1_RSA(self.evp)) as uint + fn size(&self) -> uint { + unsafe { + libcrypto::RSA_size(libcrypto::EVP_PKEY_get1_RSA(self.evp)) as uint + } } /** * Returns whether this pkey object can perform the specified role. */ - fn can(r: Role) -> bool { + fn can(&self, r: Role) -> bool { match r { Encrypt => match self.parts { @@ -203,63 +226,69 @@ pub impl PKey { * Returns the maximum amount of data that can be encrypted by an encrypt() * call. */ - fn max_data() -> uint unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + fn max_data(&self) -> uint { + unsafe { + let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); + let len = libcrypto::RSA_size(rsa); - // 41 comes from RSA_public_encrypt(3) for OAEP - len as uint - 41u + // 41 comes from RSA_public_encrypt(3) for OAEP + len as uint - 41u + } } - fn encrypt_with_padding(s: &[u8], padding: EncryptionPadding) -> ~[u8] unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { + unsafe { + let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); + let len = libcrypto::RSA_size(rsa); - assert s.len() < self.max_data(); + assert!(s.len() < self.max_data()); - let mut r = vec::from_elem(len as uint + 1u, 0u8); + let mut r = vec::from_elem(len as uint + 1u, 0u8); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_public_encrypt( - s_len as c_uint, - ps, - pr, - rsa, - openssl_padding_code(padding) - ); + do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + let rv = libcrypto::RSA_public_encrypt( + s_len as c_uint, + ps, + pr, + rsa, + openssl_padding_code(padding) + ); - if rv < 0 as c_int { - ~[] - } else { - vec::slice(r, 0u, rv as uint) + if rv < 0 as c_int { + ~[] + } else { + vec::const_slice(r, 0u, rv as uint).to_owned() + } } } } } - fn decrypt_with_padding(s: &[u8], padding: EncryptionPadding) -> ~[u8] unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { + unsafe { + let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); + let len = libcrypto::RSA_size(rsa); - assert s.len() as c_uint == libcrypto::RSA_size(rsa); + assert!(s.len() as c_uint == libcrypto::RSA_size(rsa)); - let mut r = vec::from_elem(len as uint + 1u, 0u8); + let mut r = vec::from_elem(len as uint + 1u, 0u8); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_private_decrypt( - s_len as c_uint, - ps, - pr, - rsa, - openssl_padding_code(padding) - ); + do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + let rv = libcrypto::RSA_private_decrypt( + s_len as c_uint, + ps, + pr, + rsa, + openssl_padding_code(padding) + ); - if rv < 0 as c_int { - ~[] - } else { - vec::slice(r, 0u, rv as uint) + if rv < 0 as c_int { + ~[] + } else { + vec::const_slice(r, 0u, rv as uint).to_owned() + } } } } @@ -269,66 +298,70 @@ pub impl PKey { * Encrypts data using OAEP padding, returning the encrypted data. The * supplied data must not be larger than max_data(). */ - fn encrypt(s: &[u8]) -> ~[u8] unsafe { self.encrypt_with_padding(s, OAEP) } + fn encrypt(&self, s: &[u8]) -> ~[u8] { unsafe { self.encrypt_with_padding(s, OAEP) } } /** * Decrypts data, expecting OAEP padding, returning the decrypted data. */ - fn decrypt(s: &[u8]) -> ~[u8] unsafe { self.decrypt_with_padding(s, OAEP) } + fn decrypt(&self, s: &[u8]) -> ~[u8] { unsafe { self.decrypt_with_padding(s, OAEP) } } /** * 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 { self.sign_with_hash(s, SHA256) } + fn sign(&self, 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 verify(&self, 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); + fn sign_with_hash(&self, 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); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let plen = ptr::addr_of(&len); + do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + let plen = ptr::addr_of(&len); - let rv = libcrypto::RSA_sign( - openssl_hash_nid(hash), - ps, - s_len as c_uint, - pr, - plen, - rsa); + let rv = libcrypto::RSA_sign( + openssl_hash_nid(hash), + ps, + s_len as c_uint, + pr, + plen, + rsa); - if rv < 0 as c_int { - ~[] - } else { - vec::slice(r, 0u, *plen as uint) + if rv < 0 as c_int { + ~[] + } else { + vec::const_slice(r, 0u, *plen as uint).to_owned() + } } } } } - fn verify_with_hash(m: &[u8], s: &[u8], hash: HashType) -> bool unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); + fn verify_with_hash(&self, 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| { - let rv = libcrypto::RSA_verify( - openssl_hash_nid(hash), - pm, - m_len as c_uint, - ps, - s_len as c_uint, - rsa - ); + do vec::as_imm_buf(m) |pm, m_len| { + do vec::as_imm_buf(s) |ps, s_len| { + let rv = libcrypto::RSA_verify( + openssl_hash_nid(hash), + pm, + m_len as c_uint, + ps, + s_len as c_uint, + rsa + ); - rv == 1 as c_int + rv == 1 as c_int + } } } } @@ -336,90 +369,93 @@ pub impl PKey { #[cfg(test)] mod tests { + use super::*; + use hash::{MD5, SHA1}; + #[test] fn test_gen_pub() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut k1 = PKey(); k0.gen(512u); k1.load_pub(k0.save_pub()); - assert(k0.save_pub() == k1.save_pub()); - assert(k0.size() == k1.size()); - assert(k0.can(Encrypt)); - assert(k0.can(Decrypt)); - assert(k0.can(Verify)); - assert(k0.can(Sign)); - assert(k1.can(Encrypt)); - assert(!k1.can(Decrypt)); - assert(k1.can(Verify)); - assert(!k1.can(Sign)); + assert!(k0.save_pub() == k1.save_pub()); + assert!(k0.size() == k1.size()); + assert!(k0.can(Encrypt)); + assert!(k0.can(Decrypt)); + assert!(k0.can(Verify)); + assert!(k0.can(Sign)); + assert!(k1.can(Encrypt)); + assert!(!k1.can(Decrypt)); + assert!(k1.can(Verify)); + assert!(!k1.can(Sign)); } #[test] fn test_gen_priv() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut k1 = PKey(); k0.gen(512u); k1.load_priv(k0.save_priv()); - assert(k0.save_priv() == k1.save_priv()); - assert(k0.size() == k1.size()); - assert(k0.can(Encrypt)); - assert(k0.can(Decrypt)); - assert(k0.can(Verify)); - assert(k0.can(Sign)); - assert(k1.can(Encrypt)); - assert(k1.can(Decrypt)); - assert(k1.can(Verify)); - assert(k1.can(Sign)); + assert!(k0.save_priv() == k1.save_priv()); + assert!(k0.size() == k1.size()); + assert!(k0.can(Encrypt)); + assert!(k0.can(Decrypt)); + assert!(k0.can(Verify)); + assert!(k0.can(Sign)); + assert!(k1.can(Encrypt)); + assert!(k1.can(Decrypt)); + assert!(k1.can(Verify)); + assert!(k1.can(Sign)); } #[test] fn test_encrypt() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut k1 = PKey(); let msg = ~[0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; k0.gen(512u); k1.load_pub(k0.save_pub()); let emsg = k1.encrypt(msg); let dmsg = k0.decrypt(emsg); - assert(msg == dmsg); + assert!(msg == dmsg); } #[test] fn test_encrypt_pkcs() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut k1 = PKey(); let msg = ~[0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; k0.gen(512u); k1.load_pub(k0.save_pub()); let emsg = k1.encrypt_with_padding(msg, PKCS1v15); let dmsg = k0.decrypt_with_padding(emsg, PKCS1v15); - assert(msg == dmsg); + assert!(msg == dmsg); } #[test] fn test_sign() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut k1 = PKey(); let msg = ~[0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; k0.gen(512u); k1.load_pub(k0.save_pub()); let sig = k0.sign(msg); let rv = k1.verify(msg, sig); - assert(rv == true); + assert!(rv == true); } #[test] fn test_sign_hashes() { - let k0 = PKey(); - let k1 = PKey(); + let mut k0 = PKey(); + let mut 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); + assert!(k1.verify_with_hash(msg, sig, MD5)); + assert!(!k1.verify_with_hash(msg, sig, SHA1)); } } diff --git a/rand.rs b/rand.rs index 72acdd19..96565084 100644 --- a/rand.rs +++ b/rand.rs @@ -1,4 +1,4 @@ -use libc::{c_uchar, c_int}; +use core::libc::c_int; #[link_name = "crypto"] #[abi = "cdecl"] @@ -10,8 +10,10 @@ pub fn rand_bytes(len: uint) -> ~[u8] { let mut out = vec::with_capacity(len); do vec::as_mut_buf(out) |out_buf, len| { - let r = libcrypto::RAND_bytes(out_buf, len as c_int); - if r != 1 as c_int { fail } + unsafe { + let r = libcrypto::RAND_bytes(out_buf, len as c_int); + if r != 1 as c_int { fail!() } + } } unsafe { vec::raw::set_len(&mut out, len); } @@ -21,6 +23,8 @@ pub fn rand_bytes(len: uint) -> ~[u8] { #[cfg(test)] mod tests { + use super::*; + #[test] fn test_rand_bytes() { let bytes = rand_bytes(32u); diff --git a/symm.rs b/symm.rs index 8c036333..135d2b31 100644 --- a/symm.rs +++ b/symm.rs @@ -1,8 +1,4 @@ -use libc::{c_int, c_uint}; - -export encryptmode, decryptmode; -export encrypt, decrypt; -export libcrypto; +use core::libc::{c_int, c_uint}; #[allow(non_camel_case_types)] type EVP_CIPHER_CTX = *libc::c_void; @@ -18,13 +14,13 @@ extern mod libcrypto { fn EVP_aes_128_ecb() -> EVP_CIPHER; fn EVP_aes_128_cbc() -> EVP_CIPHER; - fn EVP_aes_128_ctr() -> EVP_CIPHER; - fn EVP_aes_128_gcm() -> EVP_CIPHER; + // fn EVP_aes_128_ctr() -> EVP_CIPHER; + // fn EVP_aes_128_gcm() -> EVP_CIPHER; fn EVP_aes_256_ecb() -> EVP_CIPHER; fn EVP_aes_256_cbc() -> EVP_CIPHER; - fn EVP_aes_256_ctr() -> EVP_CIPHER; - fn EVP_aes_256_gcm() -> EVP_CIPHER; + // fn EVP_aes_256_ctr() -> EVP_CIPHER; + // fn EVP_aes_256_gcm() -> EVP_CIPHER; fn EVP_rc4() -> EVP_CIPHER; @@ -44,30 +40,32 @@ pub enum Mode { pub enum Type { AES_128_ECB, AES_128_CBC, - AES_128_CTR, + // AES_128_CTR, //AES_128_GCM, AES_256_ECB, AES_256_CBC, - AES_256_CTR, + // AES_256_CTR, //AES_256_GCM, RC4_128, } fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { - match t { - AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), - AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), - AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 0u), - //AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), + unsafe { + match t { + AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), + AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), + // AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 0u), + //AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), - AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), - AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), - AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 0u), - //AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), + AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), + AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), + // AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 0u), + //AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), - RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), + RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), + } } } @@ -80,9 +78,11 @@ pub struct Crypter { } pub fn Crypter(t: Type) -> Crypter { - let ctx = libcrypto::EVP_CIPHER_CTX_new(); - let (evp, keylen, blocksz) = evpc(t); - Crypter { evp: evp, ctx: ctx, keylen: keylen, blocksize: blocksz } + unsafe { + let ctx = libcrypto::EVP_CIPHER_CTX_new(); + let (evp, keylen, blocksz) = evpc(t); + Crypter { evp: evp, ctx: ctx, keylen: keylen, blocksize: blocksz } + } } pub impl Crypter { @@ -90,32 +90,36 @@ pub impl Crypter { * Enables or disables padding. If padding is disabled, total amount of * data encrypted must be a multiple of block size. */ - fn pad(padding: bool) { + fn pad(&self, padding: bool) { if self.blocksize > 0 { - let v = if padding { 1 } else { 0 } as c_int; - libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + unsafe { + let v = if padding { 1 } else { 0 } as c_int; + libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + } } } /** * Initializes this crypter. */ - fn init(mode: Mode, key: &[u8], iv: &[u8]) unsafe { - let mode = match mode { - Encrypt => 1 as c_int, - Decrypt => 0 as c_int, - }; - assert key.len() == self.keylen; + fn init(&self, mode: Mode, key: &[u8], iv: &[u8]) { + unsafe { + let mode = match mode { + Encrypt => 1 as c_int, + Decrypt => 0 as c_int, + }; + assert!(key.len() == self.keylen); - do vec::as_imm_buf(key) |pkey, _len| { - do vec::as_imm_buf(iv) |piv, _len| { - libcrypto::EVP_CipherInit( - self.ctx, - self.evp, - pkey, - piv, - mode - ) + do vec::as_imm_buf(key) |pkey, _len| { + do vec::as_imm_buf(iv) |piv, _len| { + libcrypto::EVP_CipherInit( + self.ctx, + self.evp, + pkey, + piv, + mode + ) + } } } } @@ -124,45 +128,49 @@ pub impl Crypter { * Update this crypter with more data to encrypt or decrypt. Returns * encrypted or decrypted bytes. */ - fn update(data: &[u8]) -> ~[u8] unsafe { - do vec::as_imm_buf(data) |pdata, len| { - let mut res = vec::from_elem(len + self.blocksize, 0u8); + fn update(&self, data: &[u8]) -> ~[u8] { + unsafe { + do vec::as_imm_buf(data) |pdata, len| { + let mut res = vec::from_elem(len + self.blocksize, 0u8); - let reslen = do vec::as_mut_buf(res) |pres, _len| { - let mut reslen = (len + self.blocksize) as u32; + let reslen = do vec::as_mut_buf(res) |pres, _len| { + let mut reslen = (len + self.blocksize) as u32; - libcrypto::EVP_CipherUpdate( - self.ctx, - pres, - &mut reslen, - pdata, - len as c_int - ); + libcrypto::EVP_CipherUpdate( + self.ctx, + pres, + &mut reslen, + pdata, + len as c_int + ); - reslen - }; + reslen + }; - vec::slice(res, 0u, reslen as uint) + vec::slice(res, 0u, reslen as uint).to_owned() + } } } /** * Finish crypting. Returns the remaining partial block of output, if any. */ - fn final() -> ~[u8] unsafe { - let res = vec::to_mut(vec::from_elem(self.blocksize, 0u8)); + fn final(&self) -> ~[u8] { + unsafe { + let mut res = vec::from_elem(self.blocksize, 0u8); - io::println(fmt!("final, res %? long", res.len())); + io::println(fmt!("final, res %? long", res.len())); - let reslen = do vec::as_mut_buf(res) |pres, _len| { - let mut reslen = self.blocksize as c_int; - libcrypto::EVP_CipherFinal(self.ctx, pres, &mut reslen); - reslen - }; + let reslen = do vec::as_mut_buf(res) |pres, _len| { + let mut reslen = self.blocksize as c_int; + libcrypto::EVP_CipherFinal(self.ctx, pres, &mut reslen); + reslen + }; - io::println(fmt!("openssl says %? bytes", reslen)); + io::println(fmt!("openssl says %? bytes", reslen)); - vec::slice(res, 0u, reslen as uint) + vec::slice(res, 0u, reslen as uint).to_owned() + } } } @@ -170,7 +178,7 @@ pub impl Crypter { * Encrypts data, using the specified crypter type in encrypt mode with the * specified key and iv; returns the resulting (encrypted) data. */ -fn encrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { +pub fn encrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { let c = Crypter(t); c.init(Encrypt, key, iv); let r = c.update(data); @@ -182,7 +190,7 @@ fn encrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { * Decrypts data, using the specified crypter type in decrypt mode with the * specified key and iv; returns the resulting (decrypted) data. */ -fn decrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { +pub fn decrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { let c = Crypter(t); c.init(Decrypt, key, iv); let r = c.update(data); @@ -192,6 +200,8 @@ fn decrypt(t: Type, key: &[u8], iv: ~[u8], data: &[u8]) -> ~[u8] { #[cfg(test)] mod tests { + use super::*; + use hex::FromHex; // Test vectors from FIPS-197: @@ -213,11 +223,11 @@ mod tests { c.init(Encrypt, k0, ~[]); c.pad(false); let r0 = c.update(p0) + c.final(); - assert(r0 == c0); + assert!(r0 == c0); c.init(Decrypt, k0, ~[]); c.pad(false); let p1 = c.update(r0) + c.final(); - assert(p1 == p0); + assert!(p1 == p0); } fn cipher_test(ciphertype: Type, pt: ~str, ct: ~str, key: ~str, iv: ~str) { @@ -236,7 +246,7 @@ mod tests { io::println(fmt!("Lengths differ: %u in computed vs %u expected", computed.len(), expected.len())); } - fail ~"test failure"; + fail!(~"test failure"); } } @@ -251,7 +261,7 @@ mod tests { cipher_test(RC4_128, pt, ct, key, iv); } - #[test] + /*#[test] fn test_aes128_ctr() { let pt = ~"6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"; @@ -260,9 +270,9 @@ mod tests { let iv = ~"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"; cipher_test(AES_128_CTR, pt, ct, key, iv); - } + }*/ - #[test] + /*#[test] fn test_aes128_gcm() { // Test case 3 in GCM spec let pt = ~"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"; @@ -271,6 +281,6 @@ mod tests { let iv = ~"cafebabefacedbaddecaf888"; cipher_test(AES_128_GCM, pt, ct, key, iv); - } + }*/ } From 1df28f42939532ebb32257c61e6a868a5153a8f5 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 20 Apr 2013 13:47:34 -0700 Subject: [PATCH 10/23] Remove debug prints in Crypter::final() --- symm.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/symm.rs b/symm.rs index 135d2b31..f1ba5235 100644 --- a/symm.rs +++ b/symm.rs @@ -159,16 +159,12 @@ pub impl Crypter { unsafe { let mut res = vec::from_elem(self.blocksize, 0u8); - io::println(fmt!("final, res %? long", res.len())); - let reslen = do vec::as_mut_buf(res) |pres, _len| { let mut reslen = self.blocksize as c_int; libcrypto::EVP_CipherFinal(self.ctx, pres, &mut reslen); reslen }; - io::println(fmt!("openssl says %? bytes", reslen)); - vec::slice(res, 0u, reslen as uint).to_owned() } } From f824a241d4828a579fdfc08ee884bc8c576a525f Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Fri, 10 May 2013 20:19:25 -0700 Subject: [PATCH 11/23] Tweak for rust trunk (c081ffb 2013-04-30 02:21:37 -0700) --- pkey.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pkey.rs b/pkey.rs index a3533778..87fcc6a6 100644 --- a/pkey.rs +++ b/pkey.rs @@ -76,13 +76,13 @@ fn openssl_hash_nid(hash: HashType) -> c_int { fn rsa_to_any(rsa: *RSA) -> *ANYKEY { unsafe { - cast::reinterpret_cast(&rsa) + cast::transmute_copy(&rsa) } } fn any_to_rsa(anykey: *ANYKEY) -> *RSA { unsafe { - cast::reinterpret_cast(&anykey) + cast::transmute_copy(&anykey) } } @@ -325,20 +325,18 @@ pub impl PKey { do vec::as_mut_buf(r) |pr, _len| { do vec::as_imm_buf(s) |ps, s_len| { - let plen = ptr::addr_of(&len); - let rv = libcrypto::RSA_sign( openssl_hash_nid(hash), ps, s_len as c_uint, pr, - plen, + &len, rsa); if rv < 0 as c_int { ~[] } else { - vec::const_slice(r, 0u, *plen as uint).to_owned() + vec::const_slice(r, 0u, len as uint).to_owned() } } } From 4e79896c962699e92e29bba97a07987cf26dec25 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Fri, 10 May 2013 20:22:14 -0700 Subject: [PATCH 12/23] Remove unnecessary `unsafe` blocks --- hash.rs | 8 +++----- hex.rs | 12 ++++-------- pkey.rs | 36 ++++++++++++++++-------------------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/hash.rs b/hash.rs index 14b39aa4..78dfd08e 100644 --- a/hash.rs +++ b/hash.rs @@ -98,11 +98,9 @@ pub impl Hasher { * value */ pub fn hash(t: HashType, data: &[u8]) -> ~[u8] { - unsafe { - let h = Hasher(t); - h.update(data); - h.final() - } + let h = Hasher(t); + h.update(data); + h.final() } #[cfg(test)] diff --git a/hex.rs b/hex.rs index 2193e49c..abd62e8a 100644 --- a/hex.rs +++ b/hex.rs @@ -34,10 +34,8 @@ impl<'self> ToHex for &'self [u8] { let xhi = (x >> 4) & 0x0F; let xlo = (x ) & 0x0F; - unsafe { - str::push_char(&mut s, chars[xhi]); - str::push_char(&mut s, chars[xlo]); - } + str::push_char(&mut s, chars[xhi]); + str::push_char(&mut s, chars[xlo]); } s @@ -61,9 +59,7 @@ impl<'self> FromHex for &'self str { else { fail!(~"bad hex character"); }; if i % 2 == 0 { - unsafe { - vec::push(&mut vec, nibble << 4); - } + vec::push(&mut vec, nibble << 4); } else { vec[i/2] |= nibble; @@ -89,4 +85,4 @@ mod tests { } -} \ No newline at end of file +} diff --git a/pkey.rs b/pkey.rs index 87fcc6a6..bdd18ada 100644 --- a/pkey.rs +++ b/pkey.rs @@ -100,18 +100,16 @@ pub fn PKey() -> PKey { ///Represents a public key, optionally with a private key attached. priv impl PKey { priv fn _tostr(&self, f: @fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { - unsafe { - let buf = ptr::mut_null(); - let len = f(self.evp, &buf); - if len < 0 as c_int { return ~[]; } - let mut s = vec::from_elem(len as uint, 0u8); + let buf = ptr::mut_null(); + let len = f(self.evp, &buf); + if len < 0 as c_int { return ~[]; } + let mut s = vec::from_elem(len as uint, 0u8); - let r = do vec::as_mut_buf(s) |ps, _len| { - f(self.evp, &ps) - }; + let r = do vec::as_mut_buf(s) |ps, _len| { + f(self.evp, &ps) + }; - vec::slice(s, 0u, r as uint).to_owned() - } + vec::slice(s, 0u, r as uint).to_owned() } priv fn _fromstr( @@ -119,12 +117,10 @@ priv impl PKey { s: &[u8], f: @fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY ) { - unsafe { - do vec::as_imm_buf(s) |ps, len| { - let evp = ptr::null(); - f(6 as c_int, &evp, &ps, len as c_uint); - self.evp = evp; - } + do vec::as_imm_buf(s) |ps, len| { + let evp = ptr::null(); + f(6 as c_int, &evp, &ps, len as c_uint); + self.evp = evp; } } } @@ -298,24 +294,24 @@ pub impl PKey { * Encrypts data using OAEP padding, returning the encrypted data. The * supplied data must not be larger than max_data(). */ - fn encrypt(&self, s: &[u8]) -> ~[u8] { unsafe { self.encrypt_with_padding(s, OAEP) } } + fn encrypt(&self, s: &[u8]) -> ~[u8] { self.encrypt_with_padding(s, OAEP) } /** * Decrypts data, expecting OAEP padding, returning the decrypted data. */ - fn decrypt(&self, s: &[u8]) -> ~[u8] { unsafe { self.decrypt_with_padding(s, OAEP) } } + fn decrypt(&self, s: &[u8]) -> ~[u8] { self.decrypt_with_padding(s, OAEP) } /** * Signs data, using OpenSSL's default scheme and sha256. Unlike encrypt(), * can process an arbitrary amount of data; returns the signature. */ - fn sign(&self, s: &[u8]) -> ~[u8] { unsafe { self.sign_with_hash(s, SHA256) } } + fn sign(&self, s: &[u8]) -> ~[u8] { 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(&self, m: &[u8], s: &[u8]) -> bool { unsafe { self.verify_with_hash(m, s, SHA256) } } + fn verify(&self, m: &[u8], s: &[u8]) -> bool { self.verify_with_hash(m, s, SHA256) } fn sign_with_hash(&self, s: &[u8], hash: HashType) -> ~[u8] { unsafe { From 08cdf5fde41d533aa077fd0bed0bb718c0c32723 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Thu, 23 May 2013 23:46:45 -0700 Subject: [PATCH 13/23] Update for current incoming --- crypto.rc | 2 - hash.rs | 26 +++++----- hex.rs | 2 +- hmac.rs | 13 +++-- pkcs5.rs | 14 +++--- pkey.rs | 145 +++++++++++++++++++++++++++--------------------------- rand.rs | 8 +-- symm.rs | 40 +++++++-------- 8 files changed, 123 insertions(+), 127 deletions(-) diff --git a/crypto.rc b/crypto.rc index eeccd14f..22ba4385 100644 --- a/crypto.rc +++ b/crypto.rc @@ -20,8 +20,6 @@ uuid = "38297409-b4c2-4499-8131-a99a7e44dad3")]; #[crate_type = "lib"]; -extern mod std; // FIXME https://github.com/mozilla/rust/issues/1127 - pub mod hex; pub mod hash; pub mod hmac; diff --git a/hash.rs b/hash.rs index 78dfd08e..bd19f333 100644 --- a/hash.rs +++ b/hash.rs @@ -1,4 +1,4 @@ -use core::libc::c_uint; +use std::libc::c_uint; pub enum HashType { MD5, @@ -15,9 +15,9 @@ pub type EVP_MD_CTX = *libc::c_void; #[allow(non_camel_case_types)] pub type EVP_MD = *libc::c_void; -#[link_name = "crypto"] #[abi = "cdecl"] -extern mod libcrypto { +#[link_args = "-lcrypto"] +extern { fn EVP_MD_CTX_create() -> EVP_MD_CTX; fn EVP_md5() -> EVP_MD; @@ -35,12 +35,12 @@ extern mod libcrypto { pub fn evpmd(t: HashType) -> (EVP_MD, uint) { unsafe { match t { - 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), + MD5 => (EVP_md5(), 16u), + SHA1 => (EVP_sha1(), 20u), + SHA224 => (EVP_sha224(), 28u), + SHA256 => (EVP_sha256(), 32u), + SHA384 => (EVP_sha384(), 48u), + SHA512 => (EVP_sha512(), 64u), } } } @@ -53,7 +53,7 @@ pub struct Hasher { pub fn Hasher(ht: HashType) -> Hasher { unsafe { - let ctx = libcrypto::EVP_MD_CTX_create(); + let ctx = EVP_MD_CTX_create(); let (evp, mdlen) = evpmd(ht); let h = Hasher { evp: evp, ctx: ctx, len: mdlen }; h.init(); @@ -65,7 +65,7 @@ pub impl Hasher { /// Initializes this hasher fn init(&self) { unsafe { - libcrypto::EVP_DigestInit(self.ctx, self.evp); + EVP_DigestInit(self.ctx, self.evp); } } @@ -73,7 +73,7 @@ pub impl Hasher { fn update(&self, data: &[u8]) { unsafe { do vec::as_imm_buf(data) |pdata, len| { - libcrypto::EVP_DigestUpdate(self.ctx, pdata, len as c_uint) + EVP_DigestUpdate(self.ctx, pdata, len as c_uint) } } } @@ -86,7 +86,7 @@ pub impl Hasher { unsafe { let mut res = vec::from_elem(self.len, 0u8); do vec::as_mut_buf(res) |pres, _len| { - libcrypto::EVP_DigestFinal(self.ctx, pres, ptr::null()); + EVP_DigestFinal(self.ctx, pres, ptr::null()); } res } diff --git a/hex.rs b/hex.rs index abd62e8a..380369f4 100644 --- a/hex.rs +++ b/hex.rs @@ -23,7 +23,7 @@ pub trait ToHex { impl<'self> ToHex for &'self [u8] { fn to_hex(&self) -> ~str { - let chars = str::to_chars(~"0123456789ABCDEF"); + let chars = str::to_chars("0123456789ABCDEF"); let mut s = ~""; diff --git a/hmac.rs b/hmac.rs index dd35010f..1c9e145d 100644 --- a/hmac.rs +++ b/hmac.rs @@ -26,10 +26,9 @@ pub struct HMAC_CTX { key: [libc::c_uchar, ..128] } -#[link_name = "crypto"] +#[link_args = "-lcrypto"] #[abi = "cdecl"] -extern mod libcrypto { - +extern { fn HMAC_CTX_init(ctx: *mut HMAC_CTX, key: *u8, keylen: libc::c_int, md: EVP_MD); fn HMAC_Update(ctx: *mut HMAC_CTX, input: *u8, len: libc::c_uint); @@ -56,7 +55,7 @@ pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { mut key: [0u8, .. 128] }; - libcrypto::HMAC_CTX_init(&mut ctx, + HMAC_CTX_init(&mut ctx, vec::raw::to_ptr(key), key.len() as libc::c_int, evp); @@ -69,7 +68,7 @@ pub impl HMAC { fn update(&mut self, data: &[u8]) { unsafe { do vec::as_imm_buf(data) |pdata, len| { - libcrypto::HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) + HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) } } } @@ -79,7 +78,7 @@ pub impl HMAC { let mut res = vec::from_elem(self.len, 0u8); let mut outlen: libc::c_uint = 0; do vec::as_mut_buf(res) |pres, _len| { - libcrypto::HMAC_Final(&mut self.ctx, pres, &mut outlen); + HMAC_Final(&mut self.ctx, pres, &mut outlen); assert!(self.len == outlen as uint) } res @@ -90,7 +89,7 @@ pub impl HMAC { fn main() { let mut h = HMAC(SHA512, ~[00u8]); - h.update(~[00u8]); + h.update([00u8]); io::println(fmt!("%?", h.final())) } diff --git a/pkcs5.rs b/pkcs5.rs index ec81c333..c43999ee 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -1,12 +1,12 @@ -use core::libc::c_int; +use std::libc::c_int; -#[link_name = "crypto"] +#[link_args = "-lcrypto"] #[abi = "cdecl"] -extern mod libcrypto { +extern { fn PKCS5_PBKDF2_HMAC_SHA1(pass: *u8, passlen: c_int, - salt: *u8, saltlen: c_int, - iter: c_int, keylen: c_int, - out: *mut u8) -> c_int; + salt: *u8, saltlen: c_int, + iter: c_int, keylen: c_int, + out: *mut u8) -> c_int; } #[doc = " @@ -23,7 +23,7 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, do vec::as_mut_buf(out) |out_buf, _out_len| { unsafe { - let r = libcrypto::PKCS5_PBKDF2_HMAC_SHA1( + let r = PKCS5_PBKDF2_HMAC_SHA1( pass_buf, pass_len as c_int, salt_buf, salt_len as c_int, iter as c_int, keylen as c_int, diff --git a/pkey.rs b/pkey.rs index bdd18ada..3d8ba5f9 100644 --- a/pkey.rs +++ b/pkey.rs @@ -1,4 +1,4 @@ -use core::libc::{c_int, c_uint}; +use std::libc::{c_int, c_uint}; use hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512}; #[allow(non_camel_case_types)] @@ -10,9 +10,9 @@ type ANYKEY = *libc::c_void; #[allow(non_camel_case_types)] type RSA = *libc::c_void; -#[link_name = "crypto"] +#[link_args = "-lcrypto"] #[abi = "cdecl"] -extern mod libcrypto { +extern { fn EVP_PKEY_new() -> *EVP_PKEY; fn EVP_PKEY_free(k: *EVP_PKEY); fn EVP_PKEY_assign(k: *EVP_PKEY, t: c_int, inner: *ANYKEY); @@ -27,13 +27,13 @@ extern mod libcrypto { fn RSA_size(k: *RSA) -> c_uint; fn RSA_public_encrypt(flen: c_uint, from: *u8, to: *mut u8, k: *RSA, - pad: c_int) -> c_int; + pad: c_int) -> c_int; fn RSA_private_decrypt(flen: c_uint, from: *u8, to: *mut u8, k: *RSA, - pad: c_int) -> c_int; + pad: c_int) -> c_int; fn RSA_sign(t: c_int, m: *u8, mlen: c_uint, sig: *mut u8, siglen: *c_uint, k: *RSA) -> c_int; fn RSA_verify(t: c_int, m: *u8, mlen: c_uint, sig: *u8, siglen: c_uint, - k: *RSA) -> c_int; + k: *RSA) -> c_int; } enum Parts { @@ -93,13 +93,13 @@ pub struct PKey { pub fn PKey() -> PKey { unsafe { - PKey { evp: libcrypto::EVP_PKEY_new(), parts: Neither } + PKey { evp: EVP_PKEY_new(), parts: Neither } } } ///Represents a public key, optionally with a private key attached. priv impl PKey { - priv fn _tostr(&self, f: @fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { + priv fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { let buf = ptr::mut_null(); let len = f(self.evp, &buf); if len < 0 as c_int { return ~[]; } @@ -115,7 +115,7 @@ priv impl PKey { priv fn _fromstr( &mut self, s: &[u8], - f: @fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY + f: extern "C" unsafe fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY ) { do vec::as_imm_buf(s) |ps, len| { let evp = ptr::null(); @@ -128,7 +128,7 @@ priv impl PKey { pub impl PKey { fn gen(&mut self, keysz: uint) { unsafe { - let rsa = libcrypto::RSA_generate_key( + let rsa = RSA_generate_key( keysz as c_uint, 65537u as c_uint, ptr::null(), @@ -137,7 +137,7 @@ pub impl PKey { let rsa_ = rsa_to_any(rsa); // XXX: 6 == NID_rsaEncryption - libcrypto::EVP_PKEY_assign(self.evp, 6 as c_int, rsa_); + EVP_PKEY_assign(self.evp, 6 as c_int, rsa_); self.parts = Both; } } @@ -147,7 +147,7 @@ pub impl PKey { */ fn save_pub(&self) -> ~[u8] { unsafe { - self._tostr(libcrypto::i2d_PublicKey) + self._tostr(i2d_PublicKey) } } @@ -156,7 +156,7 @@ pub impl PKey { */ fn load_pub(&mut self, s: &[u8]) { unsafe { - self._fromstr(s, libcrypto::d2i_PublicKey); + self._fromstr(s, d2i_PublicKey); self.parts = Public; } } @@ -167,7 +167,7 @@ pub impl PKey { */ fn save_priv(&self, ) -> ~[u8] { unsafe { - self._tostr(libcrypto::i2d_PrivateKey) + self._tostr(i2d_PrivateKey) } } /** @@ -176,7 +176,7 @@ pub impl PKey { */ fn load_priv(&mut self, s: &[u8]) { unsafe { - self._fromstr(s, libcrypto::d2i_PrivateKey); + self._fromstr(s, d2i_PrivateKey); self.parts = Both; } } @@ -186,7 +186,7 @@ pub impl PKey { */ fn size(&self) -> uint { unsafe { - libcrypto::RSA_size(libcrypto::EVP_PKEY_get1_RSA(self.evp)) as uint + RSA_size(EVP_PKEY_get1_RSA(self.evp)) as uint } } @@ -224,8 +224,8 @@ pub impl PKey { */ fn max_data(&self) -> uint { unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + let rsa = EVP_PKEY_get1_RSA(self.evp); + let len = RSA_size(rsa); // 41 comes from RSA_public_encrypt(3) for OAEP len as uint - 41u @@ -234,58 +234,57 @@ pub impl PKey { fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + let rsa = EVP_PKEY_get1_RSA(self.evp); + let len = RSA_size(rsa); assert!(s.len() < self.max_data()); let mut r = vec::from_elem(len as uint + 1u, 0u8); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_public_encrypt( - s_len as c_uint, - ps, - pr, - rsa, - openssl_padding_code(padding) - ); - - if rv < 0 as c_int { - ~[] - } else { - vec::const_slice(r, 0u, rv as uint).to_owned() - } - } + let rv = do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + RSA_public_encrypt( + s_len as c_uint, + ps, + pr, + rsa, + openssl_padding_code(padding) + ) + } + }; + if rv < 0 as c_int { + ~[] + } else { + vec::slice(r, 0u, rv as uint).to_owned() } } } fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + let rsa = EVP_PKEY_get1_RSA(self.evp); + let len = RSA_size(rsa); - assert!(s.len() as c_uint == libcrypto::RSA_size(rsa)); + assert!(s.len() as c_uint == RSA_size(rsa)); let mut r = vec::from_elem(len as uint + 1u, 0u8); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_private_decrypt( - s_len as c_uint, - ps, - pr, - rsa, - openssl_padding_code(padding) - ); + let rv = do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + RSA_private_decrypt( + s_len as c_uint, + ps, + pr, + rsa, + openssl_padding_code(padding) + ) + } + }; - if rv < 0 as c_int { - ~[] - } else { - vec::const_slice(r, 0u, rv as uint).to_owned() - } - } + if rv < 0 as c_int { + ~[] + } else { + vec::slice(r, 0u, rv as uint).to_owned() } } } @@ -315,37 +314,37 @@ pub impl PKey { fn sign_with_hash(&self, s: &[u8], hash: HashType) -> ~[u8] { unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); - let len = libcrypto::RSA_size(rsa); + let rsa = EVP_PKEY_get1_RSA(self.evp); + let len = RSA_size(rsa); let mut r = vec::from_elem(len as uint + 1u, 0u8); - do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_sign( - openssl_hash_nid(hash), - ps, - s_len as c_uint, - pr, - &len, - rsa); + let rv = do vec::as_mut_buf(r) |pr, _len| { + do vec::as_imm_buf(s) |ps, s_len| { + RSA_sign( + openssl_hash_nid(hash), + ps, + s_len as c_uint, + pr, + &len, + rsa) + } + }; - if rv < 0 as c_int { - ~[] - } else { - vec::const_slice(r, 0u, len as uint).to_owned() - } - } + if rv < 0 as c_int { + ~[] + } else { + vec::slice(r, 0u, len as uint).to_owned() } } } fn verify_with_hash(&self, m: &[u8], s: &[u8], hash: HashType) -> bool { unsafe { - let rsa = libcrypto::EVP_PKEY_get1_RSA(self.evp); + let rsa = EVP_PKEY_get1_RSA(self.evp); do vec::as_imm_buf(m) |pm, m_len| { do vec::as_imm_buf(s) |ps, s_len| { - let rv = libcrypto::RSA_verify( + let rv = RSA_verify( openssl_hash_nid(hash), pm, m_len as c_uint, diff --git a/rand.rs b/rand.rs index 96565084..e4cf2d1a 100644 --- a/rand.rs +++ b/rand.rs @@ -1,8 +1,8 @@ -use core::libc::c_int; +use std::libc::c_int; -#[link_name = "crypto"] +#[link_args = "-lcrypto"] #[abi = "cdecl"] -extern mod libcrypto { +extern { fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int; } @@ -11,7 +11,7 @@ pub fn rand_bytes(len: uint) -> ~[u8] { do vec::as_mut_buf(out) |out_buf, len| { unsafe { - let r = libcrypto::RAND_bytes(out_buf, len as c_int); + let r = RAND_bytes(out_buf, len as c_int); if r != 1 as c_int { fail!() } } } diff --git a/symm.rs b/symm.rs index f1ba5235..1cb8ed44 100644 --- a/symm.rs +++ b/symm.rs @@ -1,4 +1,4 @@ -use core::libc::{c_int, c_uint}; +use std::libc::{c_int, c_uint}; #[allow(non_camel_case_types)] type EVP_CIPHER_CTX = *libc::c_void; @@ -6,9 +6,9 @@ type EVP_CIPHER_CTX = *libc::c_void; #[allow(non_camel_case_types)] type EVP_CIPHER = *libc::c_void; -#[link_name = "crypto"] +#[link_args = "-lcrypto"] #[abi = "cdecl"] -extern mod libcrypto { +extern { fn EVP_CIPHER_CTX_new() -> EVP_CIPHER_CTX; fn EVP_CIPHER_CTX_set_padding(ctx: EVP_CIPHER_CTX, padding: c_int); @@ -25,7 +25,7 @@ extern mod libcrypto { fn EVP_rc4() -> EVP_CIPHER; fn EVP_CipherInit(ctx: EVP_CIPHER_CTX, evp: EVP_CIPHER, - key: *u8, iv: *u8, mode: c_int); + key: *u8, iv: *u8, mode: c_int); fn EVP_CipherUpdate(ctx: EVP_CIPHER_CTX, outbuf: *mut u8, outlen: &mut c_uint, inbuf: *u8, inlen: c_int); fn EVP_CipherFinal(ctx: EVP_CIPHER_CTX, res: *mut u8, len: &mut c_int); @@ -54,17 +54,17 @@ pub enum Type { fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { unsafe { match t { - AES_128_ECB => (libcrypto::EVP_aes_128_ecb(), 16u, 16u), - AES_128_CBC => (libcrypto::EVP_aes_128_cbc(), 16u, 16u), - // AES_128_CTR => (libcrypto::EVP_aes_128_ctr(), 16u, 0u), - //AES_128_GCM => (libcrypto::EVP_aes_128_gcm(), 16u, 16u), + AES_128_ECB => (EVP_aes_128_ecb(), 16u, 16u), + AES_128_CBC => (EVP_aes_128_cbc(), 16u, 16u), + // AES_128_CTR => (EVP_aes_128_ctr(), 16u, 0u), + //AES_128_GCM => (EVP_aes_128_gcm(), 16u, 16u), - AES_256_ECB => (libcrypto::EVP_aes_256_ecb(), 32u, 16u), - AES_256_CBC => (libcrypto::EVP_aes_256_cbc(), 32u, 16u), - // AES_256_CTR => (libcrypto::EVP_aes_256_ctr(), 32u, 0u), - //AES_256_GCM => (libcrypto::EVP_aes_256_gcm(), 32u, 16u), + AES_256_ECB => (EVP_aes_256_ecb(), 32u, 16u), + AES_256_CBC => (EVP_aes_256_cbc(), 32u, 16u), + // AES_256_CTR => (EVP_aes_256_ctr(), 32u, 0u), + //AES_256_GCM => (EVP_aes_256_gcm(), 32u, 16u), - RC4_128 => (libcrypto::EVP_rc4(), 16u, 0u), + RC4_128 => (EVP_rc4(), 16u, 0u), } } } @@ -79,7 +79,7 @@ pub struct Crypter { pub fn Crypter(t: Type) -> Crypter { unsafe { - let ctx = libcrypto::EVP_CIPHER_CTX_new(); + let ctx = EVP_CIPHER_CTX_new(); let (evp, keylen, blocksz) = evpc(t); Crypter { evp: evp, ctx: ctx, keylen: keylen, blocksize: blocksz } } @@ -94,7 +94,7 @@ pub impl Crypter { if self.blocksize > 0 { unsafe { let v = if padding { 1 } else { 0 } as c_int; - libcrypto::EVP_CIPHER_CTX_set_padding(self.ctx, v); + EVP_CIPHER_CTX_set_padding(self.ctx, v); } } } @@ -112,7 +112,7 @@ pub impl Crypter { do vec::as_imm_buf(key) |pkey, _len| { do vec::as_imm_buf(iv) |piv, _len| { - libcrypto::EVP_CipherInit( + EVP_CipherInit( self.ctx, self.evp, pkey, @@ -136,7 +136,7 @@ pub impl Crypter { let reslen = do vec::as_mut_buf(res) |pres, _len| { let mut reslen = (len + self.blocksize) as u32; - libcrypto::EVP_CipherUpdate( + EVP_CipherUpdate( self.ctx, pres, &mut reslen, @@ -161,7 +161,7 @@ pub impl Crypter { let reslen = do vec::as_mut_buf(res) |pres, _len| { let mut reslen = self.blocksize as c_int; - libcrypto::EVP_CipherFinal(self.ctx, pres, &mut reslen); + EVP_CipherFinal(self.ctx, pres, &mut reslen); reslen }; @@ -216,11 +216,11 @@ mod tests { ~[ 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8, 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8 ]; let c = Crypter(AES_256_ECB); - c.init(Encrypt, k0, ~[]); + c.init(Encrypt, k0, []); c.pad(false); let r0 = c.update(p0) + c.final(); assert!(r0 == c0); - c.init(Decrypt, k0, ~[]); + c.init(Decrypt, k0, []); c.pad(false); let p1 = c.update(r0) + c.final(); assert!(p1 == p0); From 2eba04e579048bb33a7a99cb738d5d9118909026 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 29 May 2013 23:42:07 -0700 Subject: [PATCH 14/23] Update for latest incoming (3a3bf8b) --- Makefile | 2 ++ hash.rs | 4 +++- hex.rs | 2 +- hmac.rs | 15 ++++++++------- pkcs5.rs | 2 ++ pkey.rs | 5 +++-- rand.rs | 3 ++- symm.rs | 9 +++++---- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 2d55d237..62f080fe 100644 --- a/Makefile +++ b/Makefile @@ -5,3 +5,5 @@ crypto: crypto.rc $(wildcard *.rs) clean: rm -f crypto libcrypto-*.so + rm libcrypto-*.dylib + rm -rf *.dSYM diff --git a/hash.rs b/hash.rs index bd19f333..be8fb9a6 100644 --- a/hash.rs +++ b/hash.rs @@ -1,4 +1,5 @@ use std::libc::c_uint; +use std::{libc,vec,ptr}; pub enum HashType { MD5, @@ -108,6 +109,7 @@ mod tests { use super::*; use hex::FromHex; use hex::ToHex; + use std::vec; struct HashTest { input: ~[u8], @@ -125,7 +127,7 @@ mod tests { let calced = calced_raw.to_hex(); if calced != hashtest.expected_output { - io::println(fmt!("Test failed - %s != %s", calced, hashtest.expected_output)); + println(fmt!("Test failed - %s != %s", calced, hashtest.expected_output)); } assert!(calced == hashtest.expected_output); diff --git a/hex.rs b/hex.rs index 380369f4..e838080a 100644 --- a/hex.rs +++ b/hex.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -extern mod std; +use std::{str,uint,vec}; pub trait ToHex { fn to_hex(&self) -> ~str; diff --git a/hmac.rs b/hmac.rs index 1c9e145d..025c1dfe 100644 --- a/hmac.rs +++ b/hmac.rs @@ -15,6 +15,7 @@ */ use hash::*; +use std::{libc,ptr,vec}; #[allow(non_camel_case_types)] pub struct HMAC_CTX { @@ -47,12 +48,12 @@ pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { let (evp, mdlen) = evpmd(ht); let mut ctx : HMAC_CTX = HMAC_CTX { - mut md: ptr::null(), - mut md_ctx: ptr::null(), - mut i_ctx: ptr::null(), - mut o_ctx: ptr::null(), - mut key_length: 0, - mut key: [0u8, .. 128] + md: ptr::null(), + md_ctx: ptr::null(), + i_ctx: ptr::null(), + o_ctx: ptr::null(), + key_length: 0, + key: [0u8, .. 128] }; HMAC_CTX_init(&mut ctx, @@ -91,5 +92,5 @@ fn main() { h.update([00u8]); - io::println(fmt!("%?", h.final())) + println(fmt!("%?", h.final())) } diff --git a/pkcs5.rs b/pkcs5.rs index c43999ee..bd122c43 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -1,4 +1,5 @@ use std::libc::c_int; +use std::{vec,str}; #[link_args = "-lcrypto"] #[abi = "cdecl"] @@ -43,6 +44,7 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, #[cfg(test)] mod tests { use super::*; + use std::str; // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 diff --git a/pkey.rs b/pkey.rs index 3d8ba5f9..30f48938 100644 --- a/pkey.rs +++ b/pkey.rs @@ -1,4 +1,5 @@ use std::libc::{c_int, c_uint}; +use std::{libc,cast,ptr,vec}; use hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512}; #[allow(non_camel_case_types)] @@ -99,7 +100,7 @@ pub fn PKey() -> PKey { ///Represents a public key, optionally with a private key attached. priv impl PKey { - priv fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { + priv unsafe fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { let buf = ptr::mut_null(); let len = f(self.evp, &buf); if len < 0 as c_int { return ~[]; } @@ -112,7 +113,7 @@ priv impl PKey { vec::slice(s, 0u, r as uint).to_owned() } - priv fn _fromstr( + priv unsafe fn _fromstr( &mut self, s: &[u8], f: extern "C" unsafe fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY diff --git a/rand.rs b/rand.rs index e4cf2d1a..74d88952 100644 --- a/rand.rs +++ b/rand.rs @@ -1,4 +1,5 @@ use std::libc::c_int; +use std::vec; #[link_args = "-lcrypto"] #[abi = "cdecl"] @@ -28,6 +29,6 @@ mod tests { #[test] fn test_rand_bytes() { let bytes = rand_bytes(32u); - io::println(fmt!("%?", bytes)); + println(fmt!("%?", bytes)); } } diff --git a/symm.rs b/symm.rs index 1cb8ed44..e483a079 100644 --- a/symm.rs +++ b/symm.rs @@ -1,4 +1,5 @@ use std::libc::{c_int, c_uint}; +use std::{libc,vec}; #[allow(non_camel_case_types)] type EVP_CIPHER_CTX = *libc::c_void; @@ -236,11 +237,11 @@ mod tests { let computed = cipher.update(pt.from_hex()) + cipher.final(); if computed != expected { - io::println(fmt!("Computed: %s", computed.to_hex())); - io::println(fmt!("Expected: %s", expected.to_hex())); + println(fmt!("Computed: %s", computed.to_hex())); + println(fmt!("Expected: %s", expected.to_hex())); if computed.len() != expected.len() { - io::println(fmt!("Lengths differ: %u in computed vs %u expected", - computed.len(), expected.len())); + println(fmt!("Lengths differ: %u in computed vs %u expected", + computed.len(), expected.len())); } fail!(~"test failure"); } From 1a88757ca2690807304ebdd0784b853abc1b64b6 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 8 Jun 2013 17:22:54 -0700 Subject: [PATCH 15/23] Update to latest incoming (878a9b9) --- hash.rs | 8 ++++---- hex.rs | 4 ++-- hmac.rs | 6 +++--- pkey.rs | 36 ++++++++++++++++++------------------ symm.rs | 10 +++++----- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/hash.rs b/hash.rs index be8fb9a6..8d5db180 100644 --- a/hash.rs +++ b/hash.rs @@ -62,16 +62,16 @@ pub fn Hasher(ht: HashType) -> Hasher { } } -pub impl Hasher { +impl Hasher { /// Initializes this hasher - fn init(&self) { + pub fn init(&self) { unsafe { EVP_DigestInit(self.ctx, self.evp); } } /// Update this hasher with more input bytes - fn update(&self, data: &[u8]) { + pub fn update(&self, data: &[u8]) { unsafe { do vec::as_imm_buf(data) |pdata, len| { EVP_DigestUpdate(self.ctx, pdata, len as c_uint) @@ -83,7 +83,7 @@ pub impl Hasher { * Return the digest of all bytes added to this hasher since its last * initialization */ - fn final(&self) -> ~[u8] { + pub fn final(&self) -> ~[u8] { unsafe { let mut res = vec::from_elem(self.len, 0u8); do vec::as_mut_buf(res) |pres, _len| { diff --git a/hex.rs b/hex.rs index e838080a..415b86cd 100644 --- a/hex.rs +++ b/hex.rs @@ -15,6 +15,7 @@ */ use std::{str,uint,vec}; +use std::iterator::*; pub trait ToHex { fn to_hex(&self) -> ~str; @@ -50,8 +51,7 @@ impl<'self> FromHex for &'self str { fn from_hex(&self) -> ~[u8] { let mut vec = vec::with_capacity(self.len() / 2); - for str::each_chari(*self) |i,c| { - + for self.iter().enumerate().advance() |(i,c)| { let nibble = if c >= '0' && c <= '9' { (c as u8) - 0x30 } else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } diff --git a/hmac.rs b/hmac.rs index 025c1dfe..ec9c40c8 100644 --- a/hmac.rs +++ b/hmac.rs @@ -65,8 +65,8 @@ pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { } } -pub impl HMAC { - fn update(&mut self, data: &[u8]) { +impl HMAC { + pub fn update(&mut self, data: &[u8]) { unsafe { do vec::as_imm_buf(data) |pdata, len| { HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) @@ -74,7 +74,7 @@ pub impl HMAC { } } - fn final(&mut self) -> ~[u8] { + pub fn final(&mut self) -> ~[u8] { unsafe { let mut res = vec::from_elem(self.len, 0u8); let mut outlen: libc::c_uint = 0; diff --git a/pkey.rs b/pkey.rs index 30f48938..83dafd52 100644 --- a/pkey.rs +++ b/pkey.rs @@ -99,7 +99,7 @@ pub fn PKey() -> PKey { } ///Represents a public key, optionally with a private key attached. -priv impl PKey { +impl PKey { priv unsafe fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { let buf = ptr::mut_null(); let len = f(self.evp, &buf); @@ -126,8 +126,8 @@ priv impl PKey { } } -pub impl PKey { - fn gen(&mut self, keysz: uint) { +impl PKey { + pub fn gen(&mut self, keysz: uint) { unsafe { let rsa = RSA_generate_key( keysz as c_uint, @@ -146,7 +146,7 @@ pub impl PKey { /** * Returns a serialized form of the public key, suitable for load_pub(). */ - fn save_pub(&self) -> ~[u8] { + pub fn save_pub(&self) -> ~[u8] { unsafe { self._tostr(i2d_PublicKey) } @@ -155,7 +155,7 @@ pub impl PKey { /** * Loads a serialized form of the public key, as produced by save_pub(). */ - fn load_pub(&mut self, s: &[u8]) { + pub fn load_pub(&mut self, s: &[u8]) { unsafe { self._fromstr(s, d2i_PublicKey); self.parts = Public; @@ -166,7 +166,7 @@ pub impl PKey { * Returns a serialized form of the public and private keys, suitable for * load_priv(). */ - fn save_priv(&self, ) -> ~[u8] { + pub fn save_priv(&self, ) -> ~[u8] { unsafe { self._tostr(i2d_PrivateKey) } @@ -175,7 +175,7 @@ pub impl PKey { * Loads a serialized form of the public and private keys, as produced by * save_priv(). */ - fn load_priv(&mut self, s: &[u8]) { + pub fn load_priv(&mut self, s: &[u8]) { unsafe { self._fromstr(s, d2i_PrivateKey); self.parts = Both; @@ -185,7 +185,7 @@ pub impl PKey { /** * Returns the size of the public key modulus. */ - fn size(&self) -> uint { + pub fn size(&self) -> uint { unsafe { RSA_size(EVP_PKEY_get1_RSA(self.evp)) as uint } @@ -194,7 +194,7 @@ pub impl PKey { /** * Returns whether this pkey object can perform the specified role. */ - fn can(&self, r: Role) -> bool { + pub fn can(&self, r: Role) -> bool { match r { Encrypt => match self.parts { @@ -223,7 +223,7 @@ pub impl PKey { * Returns the maximum amount of data that can be encrypted by an encrypt() * call. */ - fn max_data(&self) -> uint { + pub fn max_data(&self) -> uint { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); let len = RSA_size(rsa); @@ -233,7 +233,7 @@ pub impl PKey { } } - fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { + pub fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); let len = RSA_size(rsa); @@ -261,7 +261,7 @@ pub impl PKey { } } - fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { + pub fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> ~[u8] { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); let len = RSA_size(rsa); @@ -294,26 +294,26 @@ pub impl PKey { * Encrypts data using OAEP padding, returning the encrypted data. The * supplied data must not be larger than max_data(). */ - fn encrypt(&self, s: &[u8]) -> ~[u8] { self.encrypt_with_padding(s, OAEP) } + pub fn encrypt(&self, s: &[u8]) -> ~[u8] { self.encrypt_with_padding(s, OAEP) } /** * Decrypts data, expecting OAEP padding, returning the decrypted data. */ - fn decrypt(&self, s: &[u8]) -> ~[u8] { self.decrypt_with_padding(s, OAEP) } + pub fn decrypt(&self, s: &[u8]) -> ~[u8] { self.decrypt_with_padding(s, OAEP) } /** * Signs data, using OpenSSL's default scheme and sha256. Unlike encrypt(), * can process an arbitrary amount of data; returns the signature. */ - fn sign(&self, s: &[u8]) -> ~[u8] { self.sign_with_hash(s, SHA256) } + pub fn sign(&self, s: &[u8]) -> ~[u8] { 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(&self, m: &[u8], s: &[u8]) -> bool { self.verify_with_hash(m, s, SHA256) } + pub fn verify(&self, m: &[u8], s: &[u8]) -> bool { self.verify_with_hash(m, s, SHA256) } - fn sign_with_hash(&self, s: &[u8], hash: HashType) -> ~[u8] { + pub fn sign_with_hash(&self, s: &[u8], hash: HashType) -> ~[u8] { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); let len = RSA_size(rsa); @@ -339,7 +339,7 @@ pub impl PKey { } } - fn verify_with_hash(&self, m: &[u8], s: &[u8], hash: HashType) -> bool { + pub fn verify_with_hash(&self, m: &[u8], s: &[u8], hash: HashType) -> bool { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); diff --git a/symm.rs b/symm.rs index e483a079..bd73dc9d 100644 --- a/symm.rs +++ b/symm.rs @@ -86,12 +86,12 @@ pub fn Crypter(t: Type) -> Crypter { } } -pub impl Crypter { +impl Crypter { /** * Enables or disables padding. If padding is disabled, total amount of * data encrypted must be a multiple of block size. */ - fn pad(&self, padding: bool) { + pub fn pad(&self, padding: bool) { if self.blocksize > 0 { unsafe { let v = if padding { 1 } else { 0 } as c_int; @@ -103,7 +103,7 @@ pub impl Crypter { /** * Initializes this crypter. */ - fn init(&self, mode: Mode, key: &[u8], iv: &[u8]) { + pub fn init(&self, mode: Mode, key: &[u8], iv: &[u8]) { unsafe { let mode = match mode { Encrypt => 1 as c_int, @@ -129,7 +129,7 @@ pub impl Crypter { * Update this crypter with more data to encrypt or decrypt. Returns * encrypted or decrypted bytes. */ - fn update(&self, data: &[u8]) -> ~[u8] { + pub fn update(&self, data: &[u8]) -> ~[u8] { unsafe { do vec::as_imm_buf(data) |pdata, len| { let mut res = vec::from_elem(len + self.blocksize, 0u8); @@ -156,7 +156,7 @@ pub impl Crypter { /** * Finish crypting. Returns the remaining partial block of output, if any. */ - fn final(&self) -> ~[u8] { + pub fn final(&self) -> ~[u8] { unsafe { let mut res = vec::from_elem(self.blocksize, 0u8); From 47693a5dc3bc9dde512ce9340558c55f86dcccdf Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 8 Jun 2013 17:55:35 -0700 Subject: [PATCH 16/23] Don't error on `make clean` if there is no dylib --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 62f080fe..b6729921 100644 --- a/Makefile +++ b/Makefile @@ -5,5 +5,5 @@ crypto: crypto.rc $(wildcard *.rs) clean: rm -f crypto libcrypto-*.so - rm libcrypto-*.dylib + rm -f libcrypto-*.dylib rm -rf *.dSYM From c393b2bc336f8535dc8eafced84465bbabe9842a Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 12 Jun 2013 00:45:51 -0700 Subject: [PATCH 17/23] Update for latest incoming (4a52ff0) --- hex.rs | 8 ++++---- pkcs5.rs | 13 ++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hex.rs b/hex.rs index 415b86cd..8f1c8ba5 100644 --- a/hex.rs +++ b/hex.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use std::{str,uint,vec}; +use std::{uint,vec}; use std::iterator::*; pub trait ToHex { @@ -24,7 +24,7 @@ pub trait ToHex { impl<'self> ToHex for &'self [u8] { fn to_hex(&self) -> ~str { - let chars = str::to_chars("0123456789ABCDEF"); + let chars = "0123456789ABCDEF".iter().collect::<~[char]>(); let mut s = ~""; @@ -35,8 +35,8 @@ impl<'self> ToHex for &'self [u8] { let xhi = (x >> 4) & 0x0F; let xlo = (x ) & 0x0F; - str::push_char(&mut s, chars[xhi]); - str::push_char(&mut s, chars[xlo]); + s.push_char(chars[xhi]); + s.push_char(chars[xlo]); } s diff --git a/pkcs5.rs b/pkcs5.rs index bd122c43..1d68661a 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -44,7 +44,6 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, #[cfg(test)] mod tests { use super::*; - use std::str; // Test vectors from // http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06 @@ -52,7 +51,7 @@ mod tests { fn test_pbkdf2_hmac_sha1() { assert!(pbkdf2_hmac_sha1( "password", - str::to_bytes("salt"), + "salt".as_bytes(), 1u, 20u ) == ~[ @@ -63,7 +62,7 @@ mod tests { assert!(pbkdf2_hmac_sha1( "password", - str::to_bytes("salt"), + "salt".as_bytes(), 2u, 20u ) == ~[ @@ -74,7 +73,7 @@ mod tests { assert!(pbkdf2_hmac_sha1( "password", - str::to_bytes("salt"), + "salt".as_bytes(), 4096u, 20u ) == ~[ @@ -85,7 +84,7 @@ mod tests { assert!(pbkdf2_hmac_sha1( "password", - str::to_bytes("salt"), + "salt".as_bytes(), 16777216u, 20u ) == ~[ @@ -96,7 +95,7 @@ mod tests { assert!(pbkdf2_hmac_sha1( "passwordPASSWORDpassword", - str::to_bytes("saltSALTsaltSALTsaltSALTsaltSALTsalt"), + "saltSALTsaltSALTsaltSALTsaltSALTsalt".as_bytes(), 4096u, 25u ) == ~[ @@ -108,7 +107,7 @@ mod tests { assert!(pbkdf2_hmac_sha1( "pass\x00word", - str::to_bytes("sa\x00lt"), + "sa\x00lt".as_bytes(), 4096u, 16u ) == ~[ From 9ff6dd59a192721d91629364023ad97c98d8c7e2 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sat, 15 Jun 2013 16:05:46 -0700 Subject: [PATCH 18/23] Remove unused use warning on latest incoming (eac0200) --- hex.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/hex.rs b/hex.rs index 8f1c8ba5..6675a9f2 100644 --- a/hex.rs +++ b/hex.rs @@ -15,7 +15,6 @@ */ use std::{uint,vec}; -use std::iterator::*; pub trait ToHex { fn to_hex(&self) -> ~str; From 6970ca20f12219f3aa14bac6d99967e2773b8a31 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 2 Jul 2013 14:15:41 -0700 Subject: [PATCH 19/23] Update for 0.7 --- hash.rs | 7 +++---- hex.rs | 2 +- pkey.rs | 8 ++++---- symm.rs | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hash.rs b/hash.rs index 8d5db180..688ef7fd 100644 --- a/hash.rs +++ b/hash.rs @@ -109,7 +109,6 @@ mod tests { use super::*; use hex::FromHex; use hex::ToHex; - use std::vec; struct HashTest { input: ~[u8], @@ -152,7 +151,7 @@ mod tests { HashTest(~"A510CD18F7A56852EB0319", ~"577E216843DD11573574D3FB209B97D8"), HashTest(~"AAED18DBE8938C19ED734A8D", ~"6F80FB775F27E0A4CE5C2F42FC72C5F1")]; - for vec::each(tests) |test| { + for tests.iter().advance |test| { hash_test(MD5, test); } } @@ -164,7 +163,7 @@ mod tests { HashTest(~"616263", ~"A9993E364706816ABA3E25717850C26C9CD0D89D"), ]; - for vec::each(tests) |test| { + for tests.iter().advance |test| { hash_test(SHA1, test); } } @@ -175,7 +174,7 @@ mod tests { HashTest(~"616263", ~"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD") ]; - for vec::each(tests) |test| { + for tests.iter().advance |test| { hash_test(SHA256, test); } } diff --git a/hex.rs b/hex.rs index 6675a9f2..710f572c 100644 --- a/hex.rs +++ b/hex.rs @@ -58,7 +58,7 @@ impl<'self> FromHex for &'self str { else { fail!(~"bad hex character"); }; if i % 2 == 0 { - vec::push(&mut vec, nibble << 4); + vec.push(nibble << 4); } else { vec[i/2] |= nibble; diff --git a/pkey.rs b/pkey.rs index 83dafd52..d9cdbdf1 100644 --- a/pkey.rs +++ b/pkey.rs @@ -110,7 +110,7 @@ impl PKey { f(self.evp, &ps) }; - vec::slice(s, 0u, r as uint).to_owned() + s.slice(0u, r as uint).to_owned() } priv unsafe fn _fromstr( @@ -256,7 +256,7 @@ impl PKey { if rv < 0 as c_int { ~[] } else { - vec::slice(r, 0u, rv as uint).to_owned() + r.slice(0u, rv as uint).to_owned() } } } @@ -285,7 +285,7 @@ impl PKey { if rv < 0 as c_int { ~[] } else { - vec::slice(r, 0u, rv as uint).to_owned() + r.slice(0u, rv as uint).to_owned() } } } @@ -334,7 +334,7 @@ impl PKey { if rv < 0 as c_int { ~[] } else { - vec::slice(r, 0u, len as uint).to_owned() + r.slice(0u, len as uint).to_owned() } } } diff --git a/symm.rs b/symm.rs index bd73dc9d..dc4288a7 100644 --- a/symm.rs +++ b/symm.rs @@ -148,7 +148,7 @@ impl Crypter { reslen }; - vec::slice(res, 0u, reslen as uint).to_owned() + res.slice(0u, reslen as uint).to_owned() } } } @@ -166,7 +166,7 @@ impl Crypter { reslen }; - vec::slice(res, 0u, reslen as uint).to_owned() + res.slice(0u, reslen as uint).to_owned() } } } From 867433a09778a55fa4f92a36c3fe7e70fa815bb7 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 10 Jul 2013 10:16:53 -0700 Subject: [PATCH 20/23] Update for 0.8-pre (f503e53) --- hash.rs | 4 ++-- hmac.rs | 4 ++-- pkcs5.rs | 4 ++-- pkey.rs | 20 ++++++++++---------- rand.rs | 2 +- symm.rs | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/hash.rs b/hash.rs index 688ef7fd..c55515d1 100644 --- a/hash.rs +++ b/hash.rs @@ -73,7 +73,7 @@ impl Hasher { /// Update this hasher with more input bytes pub fn update(&self, data: &[u8]) { unsafe { - do vec::as_imm_buf(data) |pdata, len| { + do data.as_imm_buf |pdata, len| { EVP_DigestUpdate(self.ctx, pdata, len as c_uint) } } @@ -86,7 +86,7 @@ impl Hasher { pub fn final(&self) -> ~[u8] { unsafe { let mut res = vec::from_elem(self.len, 0u8); - do vec::as_mut_buf(res) |pres, _len| { + do res.as_mut_buf |pres, _len| { EVP_DigestFinal(self.ctx, pres, ptr::null()); } res diff --git a/hmac.rs b/hmac.rs index ec9c40c8..1e71ed1b 100644 --- a/hmac.rs +++ b/hmac.rs @@ -68,7 +68,7 @@ pub fn HMAC(ht: HashType, key: ~[u8]) -> HMAC { impl HMAC { pub fn update(&mut self, data: &[u8]) { unsafe { - do vec::as_imm_buf(data) |pdata, len| { + do data.as_imm_buf |pdata, len| { HMAC_Update(&mut self.ctx, pdata, len as libc::c_uint) } } @@ -78,7 +78,7 @@ impl HMAC { unsafe { let mut res = vec::from_elem(self.len, 0u8); let mut outlen: libc::c_uint = 0; - do vec::as_mut_buf(res) |pres, _len| { + do res.as_mut_buf |pres, _len| { HMAC_Final(&mut self.ctx, pres, &mut outlen); assert!(self.len == outlen as uint) } diff --git a/pkcs5.rs b/pkcs5.rs index 1d68661a..ed370b8c 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -19,10 +19,10 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, assert!(keylen >= 1u); do str::as_buf(pass) |pass_buf, pass_len| { - do vec::as_imm_buf(salt) |salt_buf, salt_len| { + do salt.as_imm_buf |salt_buf, salt_len| { let mut out = vec::with_capacity(keylen); - do vec::as_mut_buf(out) |out_buf, _out_len| { + do out.as_mut_buf |out_buf, _out_len| { unsafe { let r = PKCS5_PBKDF2_HMAC_SHA1( pass_buf, pass_len as c_int, diff --git a/pkey.rs b/pkey.rs index d9cdbdf1..05832d02 100644 --- a/pkey.rs +++ b/pkey.rs @@ -106,7 +106,7 @@ impl PKey { if len < 0 as c_int { return ~[]; } let mut s = vec::from_elem(len as uint, 0u8); - let r = do vec::as_mut_buf(s) |ps, _len| { + let r = do s.as_mut_buf |ps, _len| { f(self.evp, &ps) }; @@ -118,7 +118,7 @@ impl PKey { s: &[u8], f: extern "C" unsafe fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY ) { - do vec::as_imm_buf(s) |ps, len| { + do s.as_imm_buf |ps, len| { let evp = ptr::null(); f(6 as c_int, &evp, &ps, len as c_uint); self.evp = evp; @@ -242,8 +242,8 @@ impl PKey { let mut r = vec::from_elem(len as uint + 1u, 0u8); - let rv = do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { + let rv = do r.as_mut_buf |pr, _len| { + do s.as_imm_buf |ps, s_len| { RSA_public_encrypt( s_len as c_uint, ps, @@ -270,8 +270,8 @@ impl PKey { let mut r = vec::from_elem(len as uint + 1u, 0u8); - let rv = do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { + let rv = do r.as_mut_buf |pr, _len| { + do s.as_imm_buf |ps, s_len| { RSA_private_decrypt( s_len as c_uint, ps, @@ -319,8 +319,8 @@ impl PKey { let len = RSA_size(rsa); let mut r = vec::from_elem(len as uint + 1u, 0u8); - let rv = do vec::as_mut_buf(r) |pr, _len| { - do vec::as_imm_buf(s) |ps, s_len| { + let rv = do r.as_mut_buf |pr, _len| { + do s.as_imm_buf |ps, s_len| { RSA_sign( openssl_hash_nid(hash), ps, @@ -343,8 +343,8 @@ impl PKey { unsafe { let rsa = EVP_PKEY_get1_RSA(self.evp); - do vec::as_imm_buf(m) |pm, m_len| { - do vec::as_imm_buf(s) |ps, s_len| { + do m.as_imm_buf |pm, m_len| { + do s.as_imm_buf |ps, s_len| { let rv = RSA_verify( openssl_hash_nid(hash), pm, diff --git a/rand.rs b/rand.rs index 74d88952..1d8bbff8 100644 --- a/rand.rs +++ b/rand.rs @@ -10,7 +10,7 @@ extern { pub fn rand_bytes(len: uint) -> ~[u8] { let mut out = vec::with_capacity(len); - do vec::as_mut_buf(out) |out_buf, len| { + do out.as_mut_buf |out_buf, len| { unsafe { let r = RAND_bytes(out_buf, len as c_int); if r != 1 as c_int { fail!() } diff --git a/symm.rs b/symm.rs index dc4288a7..29861cdd 100644 --- a/symm.rs +++ b/symm.rs @@ -111,8 +111,8 @@ impl Crypter { }; assert!(key.len() == self.keylen); - do vec::as_imm_buf(key) |pkey, _len| { - do vec::as_imm_buf(iv) |piv, _len| { + do key.as_imm_buf |pkey, _len| { + do iv.as_imm_buf |piv, _len| { EVP_CipherInit( self.ctx, self.evp, @@ -131,10 +131,10 @@ impl Crypter { */ pub fn update(&self, data: &[u8]) -> ~[u8] { unsafe { - do vec::as_imm_buf(data) |pdata, len| { + do data.as_imm_buf |pdata, len| { let mut res = vec::from_elem(len + self.blocksize, 0u8); - let reslen = do vec::as_mut_buf(res) |pres, _len| { + let reslen = do res.as_mut_buf |pres, _len| { let mut reslen = (len + self.blocksize) as u32; EVP_CipherUpdate( @@ -160,7 +160,7 @@ impl Crypter { unsafe { let mut res = vec::from_elem(self.blocksize, 0u8); - let reslen = do vec::as_mut_buf(res) |pres, _len| { + let reslen = do res.as_mut_buf |pres, _len| { let mut reslen = self.blocksize as c_int; EVP_CipherFinal(self.ctx, pres, &mut reslen); reslen From 80a265485819476a2e11dbdbdd4c0624477bfc80 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Fri, 26 Jul 2013 22:58:08 -0700 Subject: [PATCH 21/23] Update to latest master (0.8-pre 4989799) --- pkcs5.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkcs5.rs b/pkcs5.rs index ed370b8c..366cd71a 100644 --- a/pkcs5.rs +++ b/pkcs5.rs @@ -1,5 +1,5 @@ use std::libc::c_int; -use std::{vec,str}; +use std::vec; #[link_args = "-lcrypto"] #[abi = "cdecl"] @@ -18,7 +18,7 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, assert!(iter >= 1u); assert!(keylen >= 1u); - do str::as_buf(pass) |pass_buf, pass_len| { + do pass.as_imm_buf |pass_buf, pass_len| { do salt.as_imm_buf |salt_buf, salt_len| { let mut out = vec::with_capacity(keylen); From 61d7c3ff3a009204cba3ab6cccc6f70cc2cd1eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milos=CC=8C=20Hadz=CC=8Cic=CC=81?= Date: Tue, 6 Aug 2013 03:57:03 +0200 Subject: [PATCH 22/23] Update syntax for latest Rust master (rust 0.8-pre bbda3fa). --- hash.rs | 6 +++--- hex.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hash.rs b/hash.rs index c55515d1..88f75f67 100644 --- a/hash.rs +++ b/hash.rs @@ -151,7 +151,7 @@ mod tests { HashTest(~"A510CD18F7A56852EB0319", ~"577E216843DD11573574D3FB209B97D8"), HashTest(~"AAED18DBE8938C19ED734A8D", ~"6F80FB775F27E0A4CE5C2F42FC72C5F1")]; - for tests.iter().advance |test| { + for test in tests.iter() { hash_test(MD5, test); } } @@ -163,7 +163,7 @@ mod tests { HashTest(~"616263", ~"A9993E364706816ABA3E25717850C26C9CD0D89D"), ]; - for tests.iter().advance |test| { + for test in tests.iter() { hash_test(SHA1, test); } } @@ -174,7 +174,7 @@ mod tests { HashTest(~"616263", ~"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD") ]; - for tests.iter().advance |test| { + for test in tests.iter() { hash_test(SHA256, test); } } diff --git a/hex.rs b/hex.rs index 710f572c..b479ea18 100644 --- a/hex.rs +++ b/hex.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use std::{uint,vec}; +use std::vec; pub trait ToHex { fn to_hex(&self) -> ~str; @@ -27,7 +27,7 @@ impl<'self> ToHex for &'self [u8] { let mut s = ~""; - for uint::range(0, self.len()) |i| { + for i in range(0u, self.len()) { let x = self[i]; @@ -50,7 +50,7 @@ impl<'self> FromHex for &'self str { fn from_hex(&self) -> ~[u8] { let mut vec = vec::with_capacity(self.len() / 2); - for self.iter().enumerate().advance() |(i,c)| { + for (i,c) in self.iter().enumerate() { let nibble = if c >= '0' && c <= '9' { (c as u8) - 0x30 } else if c >= 'a' && c <= 'f' { (c as u8) - (0x61 - 10) } From b78636fa47cc13cf19a7550ab47eb8030f6d5505 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 14 Aug 2013 17:55:18 -0700 Subject: [PATCH 23/23] Update to latest rust master (0.8-pre 927aff1) --- pkey.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkey.rs b/pkey.rs index 05832d02..31439bf3 100644 --- a/pkey.rs +++ b/pkey.rs @@ -100,7 +100,7 @@ pub fn PKey() -> PKey { ///Represents a public key, optionally with a private key attached. impl PKey { - priv unsafe fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { + unsafe fn _tostr(&self, f: extern "C" unsafe fn(*EVP_PKEY, &*mut u8) -> c_int) -> ~[u8] { let buf = ptr::mut_null(); let len = f(self.evp, &buf); if len < 0 as c_int { return ~[]; } @@ -113,7 +113,7 @@ impl PKey { s.slice(0u, r as uint).to_owned() } - priv unsafe fn _fromstr( + unsafe fn _fromstr( &mut self, s: &[u8], f: extern "C" unsafe fn(c_int, &*EVP_PKEY, &*u8, c_uint) -> *EVP_PKEY