boring2/openssl/src/macros.rs

235 lines
7.3 KiB
Rust

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<F>(pem: &[u8],
callback: F)
-> Result<$t, ::error::ErrorStack>
where F: FnOnce(&mut [u8]) -> Result<usize, ::error::ErrorStack>
{
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::<F>),
&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<Vec<u8>, ::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<Vec<u8>, ::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<Vec<u8>, ::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<Vec<u8>, ::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);
}
}