Loading src/asn1/mod.rs 0 → 100644 +23 −0 Original line number Diff line number Diff line pub mod ffi { #![allow(dead_code)] #![allow(non_camel_case_types)] use libc::{c_int, c_long, c_void}; pub type ASN1_INTEGER = c_void; pub type ASN1_TIME = c_void; pub type ASN1_STRING = c_void; pub static MBSTRING_FLAG: c_int = 0x1000; pub static MBSTRING_UTF8: c_int = MBSTRING_FLAG; pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; pub static MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; pub static MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4; pub static V_ASN1_UTCTIME: c_int = 23; pub static V_ASN1_GENERALIZEDTIME: c_int = 24; extern "C" { pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; } } src/bio/mod.rs 0 → 100644 +103 −0 Original line number Diff line number Diff line use libc::{c_void, c_int}; use std::io::{IoResult, IoError, OtherIoError}; use std::io::{Reader, Writer}; use std::ptr; use ssl::error::{SslError}; pub struct MemBio { bio: *mut ffi::BIO, owned: bool } impl Drop for MemBio { fn drop(&mut self) { if self.owned { unsafe { ffi::BIO_free_all(self.bio); } } } } impl MemBio { /// Creates a new owned memory based BIO pub fn new() -> Result<MemBio, SslError> { let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; try_ssl_null!(bio); Ok(MemBio { bio: bio, owned: true }) } /// Returns a "borrow", i.e. it has no ownership pub fn borrowed(bio: *mut ffi::BIO) -> MemBio { MemBio { bio: bio, owned: false } } /// Consumes current bio and returns wrapped value /// Note that data ownership is lost and /// should be handled manually pub unsafe fn unwrap(mut self) -> *mut ffi::BIO { self.owned = false; self.bio } /// Temporarily gets wrapped value pub unsafe fn get_handle(&self) -> *mut ffi::BIO { self.bio } } impl Reader for MemBio { fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { let ret = unsafe { ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void, buf.len() as c_int) }; if ret < 0 { // FIXME: provide details from OpenSSL Err(IoError{kind: OtherIoError, desc: "mem bio read error", detail: None}) } else { Ok(ret as uint) } } } impl Writer for MemBio { fn write(&mut self, buf: &[u8]) -> IoResult<()> { let ret = unsafe { ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void, buf.len() as c_int) }; if buf.len() != ret as uint { // FIXME: provide details from OpenSSL Err(IoError{kind: OtherIoError, desc: "mem bio write error", detail: None}) } else { Ok(()) } } } pub mod ffi { #![allow(non_camel_case_types)] use libc::{c_int, c_void}; pub type BIO = c_void; pub type BIO_METHOD = c_void; extern "C" { pub fn BIO_s_mem() -> *const BIO_METHOD; pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; pub fn BIO_free_all(a: *mut BIO); pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; } } src/crypto/pkey.rs +28 −1 Original line number Diff line number Diff line use libc::{c_char, c_int, c_uint}; use libc::{c_char, c_int, c_uint, c_void}; use libc; use std::mem; use std::ptr; use bio::{mod, MemBio}; use crypto::hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD160}; use crypto::symm::{EVP_CIPHER}; use ssl::error::{SslError, StreamError}; #[allow(non_camel_case_types)] pub type EVP_PKEY = *mut libc::c_void; Loading @@ -10,6 +13,8 @@ pub type EVP_PKEY = *mut libc::c_void; #[allow(non_camel_case_types)] pub type RSA = *mut libc::c_void; pub type PrivateKeyWriteCallback = extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; #[link(name = "crypto")] extern { fn EVP_PKEY_new() -> *mut EVP_PKEY; Loading @@ -34,6 +39,11 @@ extern { k: *mut RSA) -> c_int; fn RSA_verify(t: c_int, m: *const u8, mlen: c_uint, sig: *const u8, siglen: c_uint, k: *mut RSA) -> c_int; fn PEM_write_bio_PrivateKey(bio: *mut bio::ffi::BIO, pkey: *mut EVP_PKEY, cipher: *const EVP_CIPHER, kstr: *mut c_char, klen: c_int, callback: *mut c_void, user_data: *mut c_void) -> c_int; } enum Parts { Loading Loading @@ -163,6 +173,19 @@ impl PKey { self.parts = Both; } /// Stores private key as a PEM // FIXME: also add password and encryption pub fn write_pem(&self, writer: &mut Writer/*, password: Option<String>*/) -> Result<(), SslError> { let mut mem_bio = try!(MemBio::new()); unsafe { try_ssl!(PEM_write_bio_PrivateKey(mem_bio.get_handle(), self.evp, ptr::null(), ptr::null_mut(), -1, ptr::null_mut(), ptr::null_mut())); } let buf = try!(mem_bio.read_to_end().map_err(StreamError)); writer.write(buf.as_slice()).map_err(StreamError) } /** * Returns the size of the public key modulus. */ Loading Loading @@ -326,6 +349,10 @@ impl PKey { rv == 1 as c_int } } pub unsafe fn get_handle(&self) -> *mut EVP_PKEY { return self.evp } } impl Drop for PKey { Loading src/lib.rs +7 −2 Original line number Diff line number Diff line Loading @@ -9,6 +9,11 @@ extern crate libc; extern crate serialize; extern crate sync; pub mod ssl; pub mod crypto; mod macros; mod asn1; pub mod bn; pub mod bio; pub mod crypto; pub mod ssl; pub mod x509; src/macros.rs 0 → 100644 +55 −0 Original line number Diff line number Diff line #![macro_escape] macro_rules! try_ssl_stream { ($e:expr) => ( match $e { Ok(ok) => ok, Err(err) => return Err(StreamError(err)) } ) } /// Shortcut return with SSL error if something went wrong macro_rules! try_ssl_if { ($e:expr) => ( if $e { return Err(SslError::get()) } ) } /// Shortcut return with SSL error if last error result is 0 /// (default) macro_rules! try_ssl{ ($e:expr) => (try_ssl_if!($e == 0)) } /// Shortcut return with SSL if got a null result macro_rules! try_ssl_null{ ($e:expr) => (try_ssl_if!($e == ptr::null_mut())) } /// Lifts current SSL error code into Result<(), Error> /// if expression is true /// Lifting is actually a shortcut of the following form: /// /// ```ignore /// let _ = try!(something) /// Ok(()) /// ``` macro_rules! lift_ssl_if{ ($e:expr) => ( { if $e { Err(SslError::get()) } else { Ok(()) } }) } /// Lifts current SSL error code into Result<(), Error> /// if SSL returned 0 (default error indication) macro_rules! lift_ssl { ($e:expr) => (lift_ssl_if!($e == 0)) } Loading
src/asn1/mod.rs 0 → 100644 +23 −0 Original line number Diff line number Diff line pub mod ffi { #![allow(dead_code)] #![allow(non_camel_case_types)] use libc::{c_int, c_long, c_void}; pub type ASN1_INTEGER = c_void; pub type ASN1_TIME = c_void; pub type ASN1_STRING = c_void; pub static MBSTRING_FLAG: c_int = 0x1000; pub static MBSTRING_UTF8: c_int = MBSTRING_FLAG; pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; pub static MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; pub static MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4; pub static V_ASN1_UTCTIME: c_int = 23; pub static V_ASN1_GENERALIZEDTIME: c_int = 24; extern "C" { pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; } }
src/bio/mod.rs 0 → 100644 +103 −0 Original line number Diff line number Diff line use libc::{c_void, c_int}; use std::io::{IoResult, IoError, OtherIoError}; use std::io::{Reader, Writer}; use std::ptr; use ssl::error::{SslError}; pub struct MemBio { bio: *mut ffi::BIO, owned: bool } impl Drop for MemBio { fn drop(&mut self) { if self.owned { unsafe { ffi::BIO_free_all(self.bio); } } } } impl MemBio { /// Creates a new owned memory based BIO pub fn new() -> Result<MemBio, SslError> { let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; try_ssl_null!(bio); Ok(MemBio { bio: bio, owned: true }) } /// Returns a "borrow", i.e. it has no ownership pub fn borrowed(bio: *mut ffi::BIO) -> MemBio { MemBio { bio: bio, owned: false } } /// Consumes current bio and returns wrapped value /// Note that data ownership is lost and /// should be handled manually pub unsafe fn unwrap(mut self) -> *mut ffi::BIO { self.owned = false; self.bio } /// Temporarily gets wrapped value pub unsafe fn get_handle(&self) -> *mut ffi::BIO { self.bio } } impl Reader for MemBio { fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { let ret = unsafe { ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void, buf.len() as c_int) }; if ret < 0 { // FIXME: provide details from OpenSSL Err(IoError{kind: OtherIoError, desc: "mem bio read error", detail: None}) } else { Ok(ret as uint) } } } impl Writer for MemBio { fn write(&mut self, buf: &[u8]) -> IoResult<()> { let ret = unsafe { ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void, buf.len() as c_int) }; if buf.len() != ret as uint { // FIXME: provide details from OpenSSL Err(IoError{kind: OtherIoError, desc: "mem bio write error", detail: None}) } else { Ok(()) } } } pub mod ffi { #![allow(non_camel_case_types)] use libc::{c_int, c_void}; pub type BIO = c_void; pub type BIO_METHOD = c_void; extern "C" { pub fn BIO_s_mem() -> *const BIO_METHOD; pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; pub fn BIO_free_all(a: *mut BIO); pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; } }
src/crypto/pkey.rs +28 −1 Original line number Diff line number Diff line use libc::{c_char, c_int, c_uint}; use libc::{c_char, c_int, c_uint, c_void}; use libc; use std::mem; use std::ptr; use bio::{mod, MemBio}; use crypto::hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD160}; use crypto::symm::{EVP_CIPHER}; use ssl::error::{SslError, StreamError}; #[allow(non_camel_case_types)] pub type EVP_PKEY = *mut libc::c_void; Loading @@ -10,6 +13,8 @@ pub type EVP_PKEY = *mut libc::c_void; #[allow(non_camel_case_types)] pub type RSA = *mut libc::c_void; pub type PrivateKeyWriteCallback = extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; #[link(name = "crypto")] extern { fn EVP_PKEY_new() -> *mut EVP_PKEY; Loading @@ -34,6 +39,11 @@ extern { k: *mut RSA) -> c_int; fn RSA_verify(t: c_int, m: *const u8, mlen: c_uint, sig: *const u8, siglen: c_uint, k: *mut RSA) -> c_int; fn PEM_write_bio_PrivateKey(bio: *mut bio::ffi::BIO, pkey: *mut EVP_PKEY, cipher: *const EVP_CIPHER, kstr: *mut c_char, klen: c_int, callback: *mut c_void, user_data: *mut c_void) -> c_int; } enum Parts { Loading Loading @@ -163,6 +173,19 @@ impl PKey { self.parts = Both; } /// Stores private key as a PEM // FIXME: also add password and encryption pub fn write_pem(&self, writer: &mut Writer/*, password: Option<String>*/) -> Result<(), SslError> { let mut mem_bio = try!(MemBio::new()); unsafe { try_ssl!(PEM_write_bio_PrivateKey(mem_bio.get_handle(), self.evp, ptr::null(), ptr::null_mut(), -1, ptr::null_mut(), ptr::null_mut())); } let buf = try!(mem_bio.read_to_end().map_err(StreamError)); writer.write(buf.as_slice()).map_err(StreamError) } /** * Returns the size of the public key modulus. */ Loading Loading @@ -326,6 +349,10 @@ impl PKey { rv == 1 as c_int } } pub unsafe fn get_handle(&self) -> *mut EVP_PKEY { return self.evp } } impl Drop for PKey { Loading
src/lib.rs +7 −2 Original line number Diff line number Diff line Loading @@ -9,6 +9,11 @@ extern crate libc; extern crate serialize; extern crate sync; pub mod ssl; pub mod crypto; mod macros; mod asn1; pub mod bn; pub mod bio; pub mod crypto; pub mod ssl; pub mod x509;
src/macros.rs 0 → 100644 +55 −0 Original line number Diff line number Diff line #![macro_escape] macro_rules! try_ssl_stream { ($e:expr) => ( match $e { Ok(ok) => ok, Err(err) => return Err(StreamError(err)) } ) } /// Shortcut return with SSL error if something went wrong macro_rules! try_ssl_if { ($e:expr) => ( if $e { return Err(SslError::get()) } ) } /// Shortcut return with SSL error if last error result is 0 /// (default) macro_rules! try_ssl{ ($e:expr) => (try_ssl_if!($e == 0)) } /// Shortcut return with SSL if got a null result macro_rules! try_ssl_null{ ($e:expr) => (try_ssl_if!($e == ptr::null_mut())) } /// Lifts current SSL error code into Result<(), Error> /// if expression is true /// Lifting is actually a shortcut of the following form: /// /// ```ignore /// let _ = try!(something) /// Ok(()) /// ``` macro_rules! lift_ssl_if{ ($e:expr) => ( { if $e { Err(SslError::get()) } else { Ok(()) } }) } /// Lifts current SSL error code into Result<(), Error> /// if SSL returned 0 (default error indication) macro_rules! lift_ssl { ($e:expr) => (lift_ssl_if!($e == 0)) }