aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/crypto/pkey.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/src/crypto/pkey.rs')
-rw-r--r--openssl/src/crypto/pkey.rs259
1 files changed, 144 insertions, 115 deletions
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index 741c6749..10891224 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -4,7 +4,7 @@ use std::io::prelude::*;
use std::iter::repeat;
use std::mem;
use std::ptr;
-use bio::{MemBio};
+use bio::MemBio;
use crypto::hash;
use crypto::hash::Type as HashType;
use ffi;
@@ -14,7 +14,7 @@ use ssl::error::{SslError, StreamError};
pub enum Parts {
Neither,
Public,
- Both
+ Both,
}
/// Represents a role an asymmetric key might be appropriate for.
@@ -23,31 +23,31 @@ pub enum Role {
Encrypt,
Decrypt,
Sign,
- Verify
+ Verify,
}
/// Type of encryption padding to use.
#[derive(Copy, Clone)]
pub enum EncryptionPadding {
OAEP,
- PKCS1v15
+ PKCS1v15,
}
fn openssl_padding_code(padding: EncryptionPadding) -> c_int {
match padding {
EncryptionPadding::OAEP => 4,
- EncryptionPadding::PKCS1v15 => 1
+ EncryptionPadding::PKCS1v15 => 1,
}
}
fn openssl_hash_nid(hash: HashType) -> c_int {
match hash {
- HashType::MD5 => 4, // NID_md5,
- HashType::SHA1 => 64, // NID_sha1
- HashType::SHA224 => 675, // NID_sha224
- HashType::SHA256 => 672, // NID_sha256
- HashType::SHA384 => 673, // NID_sha384
- HashType::SHA512 => 674, // NID_sha512
+ HashType::MD5 => 4, // NID_md5,
+ HashType::SHA1 => 64, // NID_sha1
+ HashType::SHA224 => 675, // NID_sha224
+ HashType::SHA256 => 672, // NID_sha256
+ HashType::SHA384 => 673, // NID_sha384
+ HashType::SHA512 => 674, // NID_sha512
HashType::RIPEMD160 => 117, // NID_ripemd160
}
}
@@ -81,32 +81,38 @@ impl PKey {
}
/// Reads private key from PEM, takes ownership of handle
- pub fn private_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> where R: Read {
+ pub fn private_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
+ where R: Read
+ {
let mut mem_bio = try!(MemBio::new());
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
unsafe {
let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
ptr::null_mut(),
- None, ptr::null_mut()));
+ None,
+ ptr::null_mut()));
Ok(PKey {
- evp: evp,
+ evp: evp,
parts: Parts::Both,
})
}
}
/// Reads public key from PEM, takes ownership of handle
- pub fn public_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> where R: Read {
+ pub fn public_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
+ where R: Read
+ {
let mut mem_bio = try!(MemBio::new());
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
unsafe {
let evp = try_ssl_null!(ffi::PEM_read_bio_PUBKEY(mem_bio.get_handle(),
- ptr::null_mut(),
- None, ptr::null_mut()));
+ ptr::null_mut(),
+ None,
+ ptr::null_mut()));
Ok(PKey {
- evp: evp,
+ evp: evp,
parts: Parts::Public,
})
}
@@ -116,7 +122,9 @@ impl PKey {
unsafe {
let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
let len = f(rsa, ptr::null());
- if len < 0 as c_int { return vec!(); }
+ if len < 0 as c_int {
+ return vec![];
+ }
let mut s = repeat(0u8).take(len as usize).collect::<Vec<_>>();
let r = f(rsa, &s.as_mut_ptr());
@@ -127,14 +135,17 @@ impl PKey {
}
}
- fn _fromstr(&mut self, s: &[u8], f: unsafe extern "C" fn(*const *mut ffi::RSA, *const *const u8, c_uint) -> *mut ffi::RSA) -> bool {
+ fn _fromstr(&mut self,
+ s: &[u8],
+ f: unsafe extern "C" fn(*const *mut ffi::RSA, *const *const u8, c_uint)
+ -> *mut ffi::RSA)
+ -> bool {
unsafe {
let rsa = ptr::null_mut();
f(&rsa, &s.as_ptr(), s.len() as c_uint);
if !rsa.is_null() {
ffi::EVP_PKEY_set1_RSA(self.evp, rsa) == 1
- }
- else {
+ } else {
false
}
}
@@ -142,18 +153,13 @@ impl PKey {
pub fn gen(&mut self, keysz: usize) {
unsafe {
- let rsa = ffi::RSA_generate_key(
- keysz as c_int,
- 65537 as c_ulong,
- ptr::null(),
- ptr::null()
- );
+ let rsa = ffi::RSA_generate_key(keysz as c_int,
+ 65537 as c_ulong,
+ ptr::null(),
+ ptr::null());
// XXX: 6 == NID_rsaEncryption
- ffi::EVP_PKEY_assign(
- self.evp,
- 6 as c_int,
- mem::transmute(rsa));
+ ffi::EVP_PKEY_assign(self.evp, 6 as c_int, mem::transmute(rsa));
self.parts = Parts::Both;
}
@@ -194,11 +200,18 @@ impl PKey {
/// Stores private key as a PEM
// FIXME: also add password and encryption
- pub fn write_pem<W: Write>(&self, writer: &mut W/*, password: Option<String>*/) -> Result<(), SslError> {
+ pub fn write_pem<W: Write>(&self,
+ writer: &mut W /* , password: Option<String> */)
+ -> Result<(), SslError> {
let mut mem_bio = try!(MemBio::new());
unsafe {
- try_ssl!(ffi::PEM_write_bio_PrivateKey(mem_bio.get_handle(), self.evp, ptr::null(),
- ptr::null_mut(), -1, None, ptr::null_mut()));
+ try_ssl!(ffi::PEM_write_bio_PrivateKey(mem_bio.get_handle(),
+ self.evp,
+ ptr::null(),
+ ptr::null_mut(),
+ -1,
+ None,
+ ptr::null_mut()));
}
let mut buf = vec![];
@@ -207,11 +220,11 @@ impl PKey {
}
/// Stores public key as a PEM
- pub fn write_pub_pem<W: Write>(&self, writer: &mut W/*, password: Option<String>*/) -> Result<(), SslError> {
+ pub fn write_pub_pem<W: Write>(&self,
+ writer: &mut W /* , password: Option<String> */)
+ -> Result<(), SslError> {
let mut mem_bio = try!(MemBio::new());
- unsafe {
- try_ssl!(ffi::PEM_write_bio_PUBKEY(mem_bio.get_handle(), self.evp))
- }
+ unsafe { try_ssl!(ffi::PEM_write_bio_PUBKEY(mem_bio.get_handle(), self.evp)) }
let mut buf = vec![];
try!(mem_bio.read_to_end(&mut buf).map_err(StreamError));
writer.write_all(&buf).map_err(StreamError)
@@ -225,8 +238,7 @@ impl PKey {
let rsa = ffi::EVP_PKEY_get1_RSA(self.evp);
if rsa.is_null() {
0
- }
- else {
+ } else {
ffi::RSA_size(rsa) as usize
}
}
@@ -237,26 +249,30 @@ impl PKey {
*/
pub fn can(&self, r: Role) -> bool {
match r {
- Role::Encrypt =>
+ Role::Encrypt => {
match self.parts {
Parts::Neither => false,
_ => true,
- },
- Role::Verify =>
+ }
+ }
+ Role::Verify => {
match self.parts {
Parts::Neither => false,
_ => true,
- },
- Role::Decrypt =>
+ }
+ }
+ Role::Decrypt => {
match self.parts {
Parts::Both => true,
_ => false,
- },
- Role::Sign =>
+ }
+ }
+ Role::Sign => {
match self.parts {
Parts::Both => true,
_ => false,
- },
+ }
+ }
}
}
@@ -289,16 +305,15 @@ impl PKey {
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));
+ 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!()
+ vec![]
} else {
r.truncate(rv as usize);
r
@@ -318,15 +333,14 @@ impl PKey {
let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
- let rv = ffi::RSA_public_encrypt(
- s.len() as c_int,
- s.as_ptr(),
- r.as_mut_ptr(),
- rsa,
- openssl_padding_code(padding));
+ let rv = ffi::RSA_public_encrypt(s.len() as c_int,
+ s.as_ptr(),
+ r.as_mut_ptr(),
+ rsa,
+ openssl_padding_code(padding));
if rv < 0 as c_int {
- vec!()
+ vec![]
} else {
r.truncate(rv as usize);
r
@@ -346,15 +360,14 @@ impl PKey {
let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
- let rv = ffi::RSA_private_decrypt(
- s.len() as c_int,
- s.as_ptr(),
- r.as_mut_ptr(),
- rsa,
- openssl_padding_code(padding));
+ let rv = ffi::RSA_private_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!()
+ vec![]
} else {
r.truncate(rv as usize);
r
@@ -374,15 +387,14 @@ impl PKey {
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));
+ 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!()
+ vec![]
} else {
r.truncate(rv as usize);
r
@@ -394,46 +406,62 @@ impl PKey {
* 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.public_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) }
+ 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) }
+ 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) }
+ pub fn public_decrypt(&self, s: &[u8]) -> Vec<u8> {
+ self.public_decrypt_with_padding(s, EncryptionPadding::PKCS1v15)
+ }
/**
* Decrypts data with the private key, expecting OAEP padding, returning the decrypted data.
*/
- pub fn decrypt(&self, s: &[u8]) -> Vec<u8> { self.private_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) }
+ 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) }
+ 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) }
+ 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
@@ -441,14 +469,18 @@ impl PKey {
* The bytes to sign must be the result of a sha256 hashing;
* returns the signature.
*/
- pub fn sign(&self, s: &[u8]) -> Vec<u8> { self.sign_with_hash(s, HashType::SHA256) }
+ pub fn sign(&self, s: &[u8]) -> Vec<u8> {
+ self.sign_with_hash(s, HashType::SHA256)
+ }
/**
* Verifies a signature s (using OpenSSL's default scheme and sha256) on the SHA256 hash of a
* message.
* Returns true if the signature is valid, and false otherwise.
*/
- pub fn verify(&self, h: &[u8], s: &[u8]) -> bool { self.verify_with_hash(h, s, HashType::SHA256) }
+ pub fn verify(&self, h: &[u8], s: &[u8]) -> bool {
+ self.verify_with_hash(h, s, HashType::SHA256)
+ }
/**
* Signs data, using OpenSSL's default scheme and add ASN.1 information for the given hash type to the
@@ -466,16 +498,15 @@ impl PKey {
let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
let mut len = 0;
- let rv = ffi::RSA_sign(
- openssl_hash_nid(hash),
- s.as_ptr(),
- s.len() as c_uint,
- r.as_mut_ptr(),
- &mut len,
- rsa);
+ let rv = ffi::RSA_sign(openssl_hash_nid(hash),
+ s.as_ptr(),
+ s.len() as c_uint,
+ r.as_mut_ptr(),
+ &mut len,
+ rsa);
if rv < 0 as c_int {
- vec!()
+ vec![]
} else {
r.truncate(len as usize);
r
@@ -490,21 +521,19 @@ impl PKey {
panic!("Could not get RSA key for verification");
}
- let rv = ffi::RSA_verify(
- openssl_hash_nid(hash),
- h.as_ptr(),
- h.len() as c_uint,
- s.as_ptr(),
- s.len() as c_uint,
- rsa
- );
+ let rv = ffi::RSA_verify(openssl_hash_nid(hash),
+ h.as_ptr(),
+ h.len() as c_uint,
+ s.as_ptr(),
+ s.len() as c_uint,
+ rsa);
rv == 1 as c_int
}
}
pub unsafe fn get_handle(&self) -> *mut ffi::EVP_PKEY {
- return self.evp
+ return self.evp;
}
pub fn public_eq(&self, other: &PKey) -> bool {
@@ -568,8 +597,8 @@ mod tests {
fn test_private_key_from_pem() {
let key_path = Path::new("test/key.pem");
let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
+ .ok()
+ .expect("Failed to open `test/key.pem`");
super::PKey::private_key_from_pem(&mut file).unwrap();
}
@@ -578,8 +607,8 @@ mod tests {
fn test_public_key_from_pem() {
let key_path = Path::new("test/key.pem.pub");
let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem.pub`");
+ .ok()
+ .expect("Failed to open `test/key.pem.pub`");
super::PKey::public_key_from_pem(&mut file).unwrap();
}
@@ -588,7 +617,7 @@ mod tests {
fn test_private_encrypt() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
- let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
k0.gen(512);
k1.load_pub(&k0.save_pub());
let emsg = k0.private_encrypt(&msg);
@@ -600,7 +629,7 @@ mod tests {
fn test_public_encrypt() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
- let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
k0.gen(512);
k1.load_pub(&k0.save_pub());
let emsg = k1.public_encrypt(&msg);
@@ -612,7 +641,7 @@ mod tests {
fn test_public_encrypt_pkcs() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
- let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
k0.gen(512);
k1.load_pub(&k0.save_pub());
let emsg = k1.public_encrypt_with_padding(&msg, super::EncryptionPadding::PKCS1v15);
@@ -624,7 +653,7 @@ mod tests {
fn test_sign() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
- let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
k0.gen(512);
k1.load_pub(&k0.save_pub());
let sig = k0.sign(&msg);
@@ -636,7 +665,7 @@ mod tests {
fn test_sign_hashes() {
let mut k0 = super::PKey::new();
let mut k1 = super::PKey::new();
- let msg = vec!(0xdeu8, 0xadu8, 0xd0u8, 0x0du8);
+ let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8];
k0.gen(512);
k1.load_pub(&k0.save_pub());
@@ -674,8 +703,8 @@ mod tests {
fn test_pem() {
let key_path = Path::new("test/key.pem");
let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
+ .ok()
+ .expect("Failed to open `test/key.pem`");
let key = super::PKey::private_key_from_pem(&mut file).unwrap();