aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/src/crypto')
-rw-r--r--openssl/src/crypto/hmac.rs22
-rw-r--r--openssl/src/crypto/pkey.rs127
-rw-r--r--openssl/src/crypto/symm.rs9
3 files changed, 131 insertions, 27 deletions
diff --git a/openssl/src/crypto/hmac.rs b/openssl/src/crypto/hmac.rs
index 5c9f7576..2c329c1b 100644
--- a/openssl/src/crypto/hmac.rs
+++ b/openssl/src/crypto/hmac.rs
@@ -21,6 +21,7 @@ use std::io::prelude::*;
use crypto::hash::Type;
use ffi;
+use ffi_extras;
#[derive(PartialEq, Copy, Clone)]
enum State {
@@ -88,9 +89,10 @@ impl HMAC {
#[inline]
fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) {
unsafe {
- let r = ffi::HMAC_Init_ex(&mut self.ctx,
- key.as_ptr(), key.len() as c_int,
- md, 0 as *const _);
+ let r = ffi_extras::HMAC_Init_ex(&mut self.ctx,
+ key.as_ptr(),
+ key.len() as c_int,
+ md, 0 as *const _);
assert_eq!(r, 1);
}
self.state = Reset;
@@ -106,9 +108,9 @@ impl HMAC {
// If the key and/or md is not supplied it's reused from the last time
// avoiding redundant initializations
unsafe {
- let r = ffi::HMAC_Init_ex(&mut self.ctx,
- 0 as *const _, 0,
- 0 as *const _, 0 as *const _);
+ let r = ffi_extras::HMAC_Init_ex(&mut self.ctx,
+ 0 as *const _, 0,
+ 0 as *const _, 0 as *const _);
assert_eq!(r, 1);
}
self.state = Reset;
@@ -120,7 +122,7 @@ impl HMAC {
self.init();
}
unsafe {
- let r = ffi::HMAC_Update(&mut self.ctx, data.as_ptr(), data.len() as c_uint);
+ let r = ffi_extras::HMAC_Update(&mut self.ctx, data.as_ptr(), data.len() as c_uint);
assert_eq!(r, 1);
}
self.state = Updated;
@@ -135,7 +137,7 @@ impl HMAC {
let mut res: Vec<u8> = repeat(0).take(md_len).collect();
unsafe {
let mut len = 0;
- let r = ffi::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len);
+ let r = ffi_extras::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len);
self.state = Finalized;
assert_eq!(len as usize, md_len);
assert_eq!(r, 1);
@@ -168,7 +170,7 @@ impl Clone for HMAC {
let mut ctx: ffi::HMAC_CTX;
unsafe {
ctx = ::std::mem::uninitialized();
- let r = ffi::HMAC_CTX_copy(&mut ctx, &self.ctx);
+ let r = ffi_extras::HMAC_CTX_copy(&mut ctx, &self.ctx);
assert_eq!(r, 1);
}
HMAC { ctx: ctx, type_: self.type_, state: self.state }
@@ -181,7 +183,7 @@ impl Drop for HMAC {
if self.state != Finalized {
let mut buf: Vec<u8> = repeat(0).take(self.type_.md_len()).collect();
let mut len = 0;
- ffi::HMAC_Final(&mut self.ctx, buf.as_mut_ptr(), &mut len);
+ ffi_extras::HMAC_Final(&mut self.ctx, buf.as_mut_ptr(), &mut len);
}
ffi::HMAC_CTX_cleanup(&mut self.ctx);
}
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index 695bd8a6..6ca0aa12 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -276,7 +276,36 @@ impl PKey {
}
}
- pub fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
+ pub fn private_encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
+ unsafe {
+ let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
+ if rsa.is_null() {
+ panic!("Could not get RSA key for encryption");
+ }
+ let len = ffi::RSA_size(rsa);
+
+ assert!(s.len() < self.max_data());
+
+ let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
+
+ let rv = ffi::RSA_private_encrypt(
+ s.len() as c_int,
+ s.as_ptr(),
+ r.as_mut_ptr(),
+ rsa,
+ openssl_padding_code(padding));
+
+ if rv < 0 as c_int {
+ // println!("{:?}", SslError::get());
+ vec!()
+ } else {
+ r.truncate(rv as usize);
+ r
+ }
+ }
+ }
+
+ pub fn public_encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
unsafe {
let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
if rsa.is_null() {
@@ -304,7 +333,7 @@ impl PKey {
}
}
- pub fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
+ pub fn private_decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
unsafe {
let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
if rsa.is_null() {
@@ -332,16 +361,78 @@ impl PKey {
}
}
+ pub fn public_decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> {
+ unsafe {
+ let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
+ if rsa.is_null() {
+ panic!("Could not get RSA key for decryption");
+ }
+ let len = ffi::RSA_size(rsa);
+
+ assert_eq!(s.len() as c_int, ffi::RSA_size(rsa));
+
+ let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
+
+ let rv = ffi::RSA_public_decrypt(
+ s.len() as c_int,
+ s.as_ptr(),
+ r.as_mut_ptr(),
+ rsa,
+ openssl_padding_code(padding));
+
+ if rv < 0 as c_int {
+ vec!()
+ } else {
+ r.truncate(rv as usize);
+ r
+ }
+ }
+ }
+
/**
- * Encrypts data using OAEP padding, returning the encrypted data. The
+ * Encrypts data with the public key, using OAEP padding, returning the encrypted data. The
* supplied data must not be larger than max_data().
*/
- pub fn encrypt(&self, s: &[u8]) -> Vec<u8> { self.encrypt_with_padding(s, EncryptionPadding::OAEP) }
+ pub fn encrypt(&self, s: &[u8]) -> Vec<u8> { self.public_encrypt_with_padding(s, EncryptionPadding::OAEP) }
+
+ /**
+ * Encrypts data with the public key, using provided padding, returning the encrypted data. The
+ * supplied data must not be larger than max_data().
+ */
+ pub fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> { self.public_encrypt_with_padding(s, padding) }
+
+ /**
+ * Encrypts data with the public key, using OAEP padding, returning the encrypted data. The
+ * supplied data must not be larger than max_data().
+ */
+ pub fn public_encrypt(&self, s: &[u8]) -> Vec<u8> { self.public_encrypt_with_padding(s, EncryptionPadding::OAEP) }
+
+ /**
+ * Decrypts data with the public key, using PKCS1v15 padding, returning the decrypted data.
+ */
+ pub fn public_decrypt(&self, s: &[u8]) -> Vec<u8> { self.public_decrypt_with_padding(s, EncryptionPadding::PKCS1v15) }
/**
- * Decrypts data, expecting OAEP padding, returning the decrypted data.
+ * Decrypts data with the private key, expecting OAEP padding, returning the decrypted data.
*/
- pub fn decrypt(&self, s: &[u8]) -> Vec<u8> { self.decrypt_with_padding(s, EncryptionPadding::OAEP) }
+ pub fn decrypt(&self, s: &[u8]) -> Vec<u8> { self.private_decrypt_with_padding(s, EncryptionPadding::OAEP) }
+
+ /**
+ * Decrypts data with the private key, using provided padding, returning the encrypted data. The
+ * supplied data must not be larger than max_data().
+ */
+ pub fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec<u8> { self.private_decrypt_with_padding(s, padding) }
+
+ /**
+ * Decrypts data with the private key, expecting OAEP padding, returning the decrypted data.
+ */
+ pub fn private_decrypt(&self, s: &[u8]) -> Vec<u8> { self.private_decrypt_with_padding(s, EncryptionPadding::OAEP) }
+
+ /**
+ * Encrypts data with the private key, using PKCS1v15 padding, returning the encrypted data. The
+ * supplied data must not be larger than max_data().
+ */
+ pub fn private_encrypt(&self, s: &[u8]) -> Vec<u8> { self.private_encrypt_with_padding(s, EncryptionPadding::PKCS1v15) }
/**
* Signs data, using OpenSSL's default scheme and adding sha256 ASN.1 information to the
@@ -493,26 +584,38 @@ mod tests {
}
#[test]
- fn test_encrypt() {
+ fn test_private_encrypt() {
+ let mut k0 = super::PKey::new();
+ let mut k1 = super::PKey::new();
+ let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ k0.gen(512);
+ k1.load_pub(&k0.save_pub());
+ let emsg = k0.private_encrypt(&msg);
+ let dmsg = k1.public_decrypt(&emsg);
+ assert!(msg == dmsg);
+ }
+
+ #[test]
+ fn test_public_encrypt() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
k0.gen(512);
k1.load_pub(&k0.save_pub());
- let emsg = k1.encrypt(&msg);
- let dmsg = k0.decrypt(&emsg);
+ let emsg = k1.public_encrypt(&msg);
+ let dmsg = k0.private_decrypt(&emsg);
assert!(msg == dmsg);
}
#[test]
- fn test_encrypt_pkcs() {
+ fn test_public_encrypt_pkcs() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
k0.gen(512);
k1.load_pub(&k0.save_pub());
- let emsg = k1.encrypt_with_padding(&msg, super::EncryptionPadding::PKCS1v15);
- let dmsg = k0.decrypt_with_padding(&emsg, super::EncryptionPadding::PKCS1v15);
+ let emsg = k1.public_encrypt_with_padding(&msg, super::EncryptionPadding::PKCS1v15);
+ let dmsg = k0.private_decrypt_with_padding(&emsg, super::EncryptionPadding::PKCS1v15);
assert!(msg == dmsg);
}
diff --git a/openssl/src/crypto/symm.rs b/openssl/src/crypto/symm.rs
index db8aa54e..bc4b65b5 100644
--- a/openssl/src/crypto/symm.rs
+++ b/openssl/src/crypto/symm.rs
@@ -1,5 +1,4 @@
use std::iter::repeat;
-use std::convert::AsRef;
use libc::{c_int};
use crypto::symm_internal::evpc;
@@ -75,7 +74,7 @@ impl Crypter {
/**
* Initializes this crypter.
*/
- pub fn init<T: AsRef<[u8]>>(&self, mode: Mode, key: &[u8], iv: T) {
+ pub fn init(&self, mode: Mode, key: &[u8], iv: &[u8]) {
unsafe {
let mode = match mode {
Mode::Encrypt => 1 as c_int,
@@ -87,7 +86,7 @@ impl Crypter {
self.ctx,
self.evp,
key.as_ptr(),
- iv.as_ref().as_ptr(),
+ iv.as_ptr(),
mode
);
}
@@ -146,7 +145,7 @@ impl Drop for Crypter {
* Encrypts data, using the specified crypter type in encrypt mode with the
* specified key and iv; returns the resulting (encrypted) data.
*/
-pub fn encrypt<T: AsRef<[u8]>>(t: Type, key: &[u8], iv: T, data: &[u8]) -> Vec<u8> {
+pub fn encrypt(t: Type, key: &[u8], iv: &[u8], data: &[u8]) -> Vec<u8> {
let c = Crypter::new(t);
c.init(Mode::Encrypt, key, iv);
let mut r = c.update(data);
@@ -159,7 +158,7 @@ pub fn encrypt<T: AsRef<[u8]>>(t: Type, key: &[u8], iv: T, data: &[u8]) -> Vec<u
* Decrypts data, using the specified crypter type in decrypt mode with the
* specified key and iv; returns the resulting (decrypted) data.
*/
-pub fn decrypt<T: AsRef<[u8]>>(t: Type, key: &[u8], iv: T, data: &[u8]) -> Vec<u8> {
+pub fn decrypt(t: Type, key: &[u8], iv: &[u8], data: &[u8]) -> Vec<u8> {
let c = Crypter::new(t);
c.init(Mode::Decrypt, key, iv);
let mut r = c.update(data);