aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/rsa.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-11-11 19:49:00 +0000
committerSteven Fackler <[email protected]>2016-11-11 20:10:10 +0000
commit6b7279eb5224a422860d0adb38becd5bca19763f (patch)
treeb74aab6be99b603ff763263439733354e92f1b4b /openssl/src/rsa.rs
parentAdd EcKey <-> PKey conversions (diff)
downloadrust-openssl-6b7279eb5224a422860d0adb38becd5bca19763f.tar.xz
rust-openssl-6b7279eb5224a422860d0adb38becd5bca19763f.zip
Consistently support both PEM and DER encodings
Closes #500
Diffstat (limited to 'openssl/src/rsa.rs')
-rw-r--r--openssl/src/rsa.rs47
1 files changed, 46 insertions, 1 deletions
diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs
index bd1d16d3..70d41997 100644
--- a/openssl/src/rsa.rs
+++ b/openssl/src/rsa.rs
@@ -1,8 +1,9 @@
use ffi;
+use std::cmp;
use std::fmt;
use std::ptr;
use std::mem;
-use libc::{c_int, c_void, c_char};
+use libc::{c_int, c_void, c_char, c_long};
use {cvt, cvt_p, cvt_n};
use bn::{BigNum, BigNumRef};
@@ -49,6 +50,26 @@ impl RsaRef {
Ok(mem_bio.get_buf().to_owned())
}
+ /// Encodes an RSA private key as unencrypted DER formatted data.
+ pub fn private_key_to_der(&self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let len = try!(cvt(ffi::i2d_RSAPrivateKey(self.as_ptr(), ptr::null_mut())));
+ let mut buf = vec![0; len as usize];
+ try!(cvt(ffi::i2d_RSAPrivateKey(self.as_ptr(), &mut buf.as_mut_ptr())));
+ Ok(buf)
+ }
+ }
+
+ /// Encodes an RSA public key as DER formatted data.
+ pub fn public_key_to_der(&self) -> Result<Vec<u8>, ErrorStack> {
+ unsafe {
+ let len = try!(cvt(ffi::i2d_RSA_PUBKEY(self.as_ptr(), ptr::null_mut())));
+ let mut buf = vec![0; len as usize];
+ try!(cvt(ffi::i2d_RSA_PUBKEY(self.as_ptr(), &mut buf.as_mut_ptr())));
+ Ok(buf)
+ }
+ }
+
pub fn size(&self) -> usize {
unsafe {
assert!(self.n().is_some());
@@ -250,6 +271,7 @@ impl Rsa {
///
/// The public exponent will be 65537.
pub fn generate(bits: u32) -> Result<Rsa, ErrorStack> {
+ ffi::init();
unsafe {
let rsa = Rsa(try!(cvt_p(ffi::RSA_new())));
let e = try!(BigNum::from_u32(ffi::RSA_F4 as u32));
@@ -260,6 +282,7 @@ impl Rsa {
/// Reads an RSA private key from PEM formatted data.
pub fn private_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> {
+ ffi::init();
let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(),
@@ -274,6 +297,7 @@ impl Rsa {
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
where F: FnOnce(&mut [c_char]) -> usize
{
+ ffi::init();
let mut cb = CallbackState::new(pass_cb);
let mem_bio = try!(MemBioSlice::new(buf));
@@ -289,6 +313,7 @@ impl Rsa {
/// Reads an RSA public key from PEM formatted data.
pub fn public_key_from_pem(buf: &[u8]) -> Result<Rsa, ErrorStack> {
+ ffi::init();
let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSA_PUBKEY(mem_bio.as_ptr(),
@@ -298,6 +323,26 @@ impl Rsa {
Ok(Rsa(rsa))
}
}
+
+ /// Reads an RSA private key from DER formatted data.
+ pub fn private_key_from_der(buf: &[u8]) -> Result<Rsa, ErrorStack> {
+ unsafe {
+ ffi::init();
+ let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long;
+ let dsa = try!(cvt_p(ffi::d2i_RSAPrivateKey(ptr::null_mut(), &mut buf.as_ptr(), len)));
+ Ok(Rsa(dsa))
+ }
+ }
+
+ /// Reads an RSA public key from DER formatted data.
+ pub fn public_key_from_der(buf: &[u8]) -> Result<Rsa, ErrorStack> {
+ unsafe {
+ ffi::init();
+ let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long;
+ let dsa = try!(cvt_p(ffi::d2i_RSA_PUBKEY(ptr::null_mut(), &mut buf.as_ptr(), len)));
+ Ok(Rsa(dsa))
+ }
+ }
}
impl fmt::Debug for Rsa {