macro_rules! type_ { ($n:ident, $r:ident, $c:path, $d:path) => { pub struct $n(*mut $c); impl ::types::OpenSslType for $n { type CType = $c; type Ref = $r; unsafe fn from_ptr(ptr: *mut $c) -> $n { $n(ptr) } } impl Drop for $n { fn drop(&mut self) { unsafe { $d(self.0) } } } impl ::std::ops::Deref for $n { type Target = $r; fn deref(&self) -> &$r { unsafe { ::types::OpenSslTypeRef::from_ptr(self.0) } } } impl ::std::ops::DerefMut for $n { fn deref_mut(&mut self) -> &mut $r { unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.0) } } } pub struct $r(::util::Opaque); impl ::types::OpenSslTypeRef for $r { type CType = $c; } } } macro_rules! private_key_from_pem { ($t:ident, $f:path) => { /// Deserializes a PEM-formatted private key. pub fn private_key_from_pem(pem: &[u8]) -> Result<$t, ::error::ErrorStack> { unsafe { ::init(); let bio = try!(::bio::MemBioSlice::new(pem)); cvt_p($f(bio.as_ptr(), ::std::ptr::null_mut(), None, ::std::ptr::null_mut())) .map($t) } } /// Deserializes a PEM-formatted private key, using the supplied password if the key is /// encrypted. /// /// # Panics /// /// Panics if `passphrase` contains an embedded null. pub fn private_key_from_pem_passphrase(pem: &[u8], passphrase: &[u8]) -> Result<$t, ::error::ErrorStack> { unsafe { ffi::init(); let bio = try!(::bio::MemBioSlice::new(pem)); let passphrase = ::std::ffi::CString::new(passphrase).unwrap(); cvt_p($f(bio.as_ptr(), ptr::null_mut(), None, passphrase.as_ptr() as *const _ as *mut _)) .map($t) } } /// Deserializes a PEM-formatted private key, using a callback to retrieve a password if the /// key is encrypted. /// /// The callback should copy the password into the provided buffer and return the number of /// bytes written. pub fn private_key_from_pem_callback(pem: &[u8], callback: F) -> Result<$t, ::error::ErrorStack> where F: FnOnce(&mut [u8]) -> Result { unsafe { ffi::init(); let mut cb = ::util::CallbackState::new(callback); let bio = try!(::bio::MemBioSlice::new(pem)); cvt_p($f(bio.as_ptr(), ptr::null_mut(), Some(::util::invoke_passwd_cb::), &mut cb as *mut _ as *mut _)) .map($t) } } } } macro_rules! private_key_to_pem { ($f:path) => { /// Serializes the private key to PEM. pub fn private_key_to_pem(&self) -> Result, ::error::ErrorStack> { unsafe { let bio = try!(::bio::MemBio::new()); try!(cvt($f(bio.as_ptr(), self.as_ptr(), ptr::null(), ptr::null_mut(), -1, None, ptr::null_mut()))); Ok(bio.get_buf().to_owned()) } } /// Serializes the private key to PEM, encrypting it with the specified symmetric cipher and /// passphrase. pub fn private_key_to_pem_passphrase(&self, cipher: ::symm::Cipher, passphrase: &[u8]) -> Result, ::error::ErrorStack> { unsafe { let bio = try!(::bio::MemBio::new()); assert!(passphrase.len() <= ::libc::c_int::max_value() as usize); try!(cvt($f(bio.as_ptr(), self.as_ptr(), cipher.as_ptr(), passphrase.as_ptr() as *const _ as *mut _, passphrase.len() as ::libc::c_int, None, ptr::null_mut()))); Ok(bio.get_buf().to_owned()) } } } } macro_rules! to_pem_inner { (#[$m:meta] $n:ident, $f:path) => { #[$m] pub fn $n(&self) -> Result, ::error::ErrorStack> { unsafe { let bio = try!(::bio::MemBio::new()); try!(cvt($f(bio.as_ptr(), self.as_ptr()))); Ok(bio.get_buf().to_owned()) } } } } macro_rules! public_key_to_pem { ($f:path) => { to_pem_inner!(/// Serializes a public key to PEM. public_key_to_pem, $f); } } macro_rules! to_pem { ($f:path) => { to_pem_inner!(/// Serializes this value to PEM. to_pem, $f); } } macro_rules! to_der_inner { (#[$m:meta] $n:ident, $f:path) => { #[$m] pub fn $n(&self) -> Result, ::error::ErrorStack> { unsafe { let len = try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), ptr::null_mut()))); let mut buf = vec![0; len as usize]; try!(::cvt($f(::types::OpenSslTypeRef::as_ptr(self), &mut buf.as_mut_ptr()))); Ok(buf) } } }; } macro_rules! to_der { ($f:path) => { to_der_inner!(/// Serializes this value to DER. to_der, $f); } } macro_rules! private_key_to_der { ($f:path) => { to_der_inner!(/// Serializes the private key to DER. private_key_to_der, $f); } } macro_rules! public_key_to_der { ($f:path) => { to_der_inner!(/// Serializes the public key to DER. public_key_to_der, $f); } } macro_rules! from_der_inner { (#[$m:meta] $n:ident, $t:ident, $f:path) => { #[$m] pub fn $n(der: &[u8]) -> Result<$t, ::error::ErrorStack> { unsafe { ::ffi::init(); let len = ::std::cmp::min(der.len(), ::libc::c_long::max_value() as usize) as ::libc::c_long; ::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len)) .map($t) } } } } macro_rules! from_der { ($t:ident, $f:path) => { from_der_inner!(/// Deserializes a value from DER-formatted data. from_der, $t, $f); } } macro_rules! private_key_from_der { ($t:ident, $f:path) => { from_der_inner!(/// Deserializes a private key from DER-formatted data. private_key_from_der, $t, $f); } } macro_rules! public_key_from_der { ($t:ident, $f:path) => { from_der_inner!(/// Deserializes a public key from DER-formatted data. public_key_from_der, $t, $f); } }