Some serialization support for EcKey
This commit is contained in:
parent
85c1474ce6
commit
08e0c4ca90
|
|
@ -1513,11 +1513,19 @@ extern {
|
||||||
user_data: *mut c_void) -> c_int;
|
user_data: *mut c_void) -> c_int;
|
||||||
pub fn PEM_write_bio_DSA_PUBKEY(bp: *mut BIO, dsa: *mut DSA) -> c_int;
|
pub fn PEM_write_bio_DSA_PUBKEY(bp: *mut BIO, dsa: *mut DSA) -> c_int;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
|
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
|
||||||
pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: *mut X509_REQ) -> c_int;
|
pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: *mut X509_REQ) -> c_int;
|
||||||
|
|
||||||
|
pub fn PEM_write_bio_ECPrivateKey(bio: *mut BIO,
|
||||||
|
key: *mut EC_KEY,
|
||||||
|
cipher: *const EVP_CIPHER,
|
||||||
|
kstr: *mut c_uchar,
|
||||||
|
klen: c_int,
|
||||||
|
callback: Option<PasswordCallback>,
|
||||||
|
user_data: *mut c_void)
|
||||||
|
-> c_int;
|
||||||
|
pub fn PEM_read_bio_ECPrivateKey(bio: *mut BIO, key: *mut *mut EC_KEY, callback: Option<PasswordCallback>, user_data: *mut c_void) -> *mut EC_KEY;
|
||||||
|
|
||||||
pub fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const c_char, passlen: c_int,
|
pub fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const c_char, passlen: c_int,
|
||||||
salt: *const u8, saltlen: c_int,
|
salt: *const u8, saltlen: c_int,
|
||||||
iter: c_int, keylen: c_int,
|
iter: c_int, keylen: c_int,
|
||||||
|
|
@ -1744,6 +1752,9 @@ extern {
|
||||||
pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
|
pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA;
|
||||||
pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
|
pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int;
|
||||||
|
|
||||||
|
pub fn d2i_ECPrivateKey(k: *mut *mut EC_KEY, pp: *mut *const c_uchar, length: c_long) -> *mut EC_KEY;
|
||||||
|
pub fn i2d_ECPrivateKey(ec_key: *mut EC_KEY, pp: *mut *mut c_uchar) -> c_int;
|
||||||
|
|
||||||
pub fn d2i_X509(a: *mut *mut X509, pp: *mut *const c_uchar, length: c_long) -> *mut X509;
|
pub fn d2i_X509(a: *mut *mut X509, pp: *mut *const c_uchar, length: c_long) -> *mut X509;
|
||||||
pub fn i2d_X509_bio(b: *mut BIO, x: *mut X509) -> c_int;
|
pub fn i2d_X509_bio(b: *mut BIO, x: *mut X509) -> c_int;
|
||||||
pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int;
|
pub fn i2d_X509_REQ_bio(b: *mut BIO, x: *mut X509_REQ) -> c_int;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use bio::{MemBio, MemBioSlice};
|
||||||
use bn::BigNumRef;
|
use bn::BigNumRef;
|
||||||
use {cvt, cvt_p};
|
use {cvt, cvt_p};
|
||||||
use types::OpenSslTypeRef;
|
use types::OpenSslTypeRef;
|
||||||
use util::{CallbackState, invoke_passwd_cb};
|
use util::{CallbackState, invoke_passwd_cb_old};
|
||||||
|
|
||||||
type_!(Dsa, DsaRef, ffi::DSA, ffi::DSA_free);
|
type_!(Dsa, DsaRef, ffi::DSA, ffi::DSA_free);
|
||||||
|
|
||||||
|
|
@ -125,25 +125,9 @@ impl Dsa {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a DSA private key from PEM formatted data.
|
private_key_from_pem!(Dsa, ffi::PEM_read_bio_DSAPrivateKey);
|
||||||
pub fn private_key_from_pem(buf: &[u8]) -> Result<Dsa, ErrorStack> {
|
|
||||||
ffi::init();
|
|
||||||
let mem_bio = try!(MemBioSlice::new(buf));
|
|
||||||
|
|
||||||
unsafe {
|
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
|
||||||
let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.as_ptr(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
None,
|
|
||||||
ptr::null_mut())));
|
|
||||||
Ok(Dsa(dsa))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a private key from PEM supplying a password callback to be invoked if the private key
|
|
||||||
/// is encrypted.
|
|
||||||
///
|
|
||||||
/// The callback will be passed the password buffer and should return the number of characters
|
|
||||||
/// placed into the buffer.
|
|
||||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
|
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Dsa, ErrorStack>
|
||||||
where F: FnOnce(&mut [c_char]) -> usize
|
where F: FnOnce(&mut [c_char]) -> usize
|
||||||
{
|
{
|
||||||
|
|
@ -155,7 +139,7 @@ impl Dsa {
|
||||||
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
||||||
let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.as_ptr(),
|
let dsa = try!(cvt_p(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.as_ptr(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
Some(invoke_passwd_cb::<F>),
|
Some(invoke_passwd_cb_old::<F>),
|
||||||
cb_ptr)));
|
cb_ptr)));
|
||||||
Ok(Dsa(dsa))
|
Ok(Dsa(dsa))
|
||||||
}
|
}
|
||||||
|
|
@ -235,8 +219,6 @@ mod compat {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use libc::c_char;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -248,14 +230,9 @@ mod test {
|
||||||
pub fn test_password() {
|
pub fn test_password() {
|
||||||
let mut password_queried = false;
|
let mut password_queried = false;
|
||||||
let key = include_bytes!("../test/dsa-encrypted.pem");
|
let key = include_bytes!("../test/dsa-encrypted.pem");
|
||||||
Dsa::private_key_from_pem_cb(key, |password| {
|
Dsa::private_key_from_pem_callback(key, |password| {
|
||||||
password_queried = true;
|
password_queried = true;
|
||||||
password[0] = b'm' as c_char;
|
password[..6].copy_from_slice(b"mypass");
|
||||||
password[1] = b'y' as c_char;
|
|
||||||
password[2] = b'p' as c_char;
|
|
||||||
password[3] = b'a' as c_char;
|
|
||||||
password[4] = b's' as c_char;
|
|
||||||
password[5] = b's' as c_char;
|
|
||||||
6
|
6
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,27 @@
|
||||||
use ffi;
|
use ffi;
|
||||||
|
use std::cmp;
|
||||||
|
use libc::c_long;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use {cvt_p, init};
|
use {cvt, cvt_p, init};
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use nid::Nid;
|
use nid::Nid;
|
||||||
|
use types::OpenSslTypeRef;
|
||||||
|
|
||||||
type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free);
|
type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free);
|
||||||
|
|
||||||
|
impl EcKeyRef {
|
||||||
|
/// Serializes the private key components to DER.
|
||||||
|
pub fn private_key_to_der(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||||
|
unsafe {
|
||||||
|
let len = try!(cvt(ffi::i2d_ECPrivateKey(self.as_ptr(), ptr::null_mut())));
|
||||||
|
let mut buf = vec![0; len as usize];
|
||||||
|
try!(cvt(ffi::i2d_ECPrivateKey(self.as_ptr(), &mut buf.as_mut_ptr())));
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EcKey {
|
impl EcKey {
|
||||||
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
|
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -13,6 +29,16 @@ impl EcKey {
|
||||||
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey)
|
cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Deserializes a DER-encoded private key.
|
||||||
|
pub fn private_key_from_der(der: &[u8]) -> Result<EcKey, ErrorStack> {
|
||||||
|
unsafe {
|
||||||
|
init();
|
||||||
|
let len = cmp::min(der.len(), c_long::max_value() as usize) as c_long;
|
||||||
|
cvt_p(ffi::d2i_ECPrivateKey(ptr::null_mut(), &mut der.as_ptr(), len)).map(EcKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private_key_from_pem!(EcKey, ffi::PEM_read_bio_ECPrivateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -19,46 +19,8 @@ use libc::c_int;
|
||||||
|
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
|
|
||||||
macro_rules! type_ {
|
#[macro_use]
|
||||||
($n:ident, $r:ident, $c:path, $d:path) => {
|
mod macros;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod bio;
|
mod bio;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
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 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]) -> usize
|
||||||
|
{
|
||||||
|
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 ::libc::c_void))
|
||||||
|
.map($t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ use dsa::Dsa;
|
||||||
use ec_key::EcKey;
|
use ec_key::EcKey;
|
||||||
use rsa::Rsa;
|
use rsa::Rsa;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use util::{CallbackState, invoke_passwd_cb};
|
use util::{CallbackState, invoke_passwd_cb_old};
|
||||||
use types::{OpenSslType, OpenSslTypeRef};
|
use types::{OpenSslType, OpenSslTypeRef};
|
||||||
|
|
||||||
type_!(PKey, PKeyRef, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
|
type_!(PKey, PKeyRef, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
|
||||||
|
|
@ -166,24 +166,9 @@ impl PKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads a private key from PEM.
|
private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey);
|
||||||
pub fn private_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
|
|
||||||
ffi::init();
|
|
||||||
let mem_bio = try!(MemBioSlice::new(buf));
|
|
||||||
unsafe {
|
|
||||||
let evp = try!(cvt_p(ffi::PEM_read_bio_PrivateKey(mem_bio.as_ptr(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
None,
|
|
||||||
ptr::null_mut())));
|
|
||||||
Ok(PKey::from_ptr(evp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a private key from PEM, supplying a password callback to be invoked if the private key
|
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
|
||||||
/// is encrypted.
|
|
||||||
///
|
|
||||||
/// The callback will be passed the password buffer and should return the number of characters
|
|
||||||
/// placed into the buffer.
|
|
||||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
|
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
|
||||||
where F: FnOnce(&mut [c_char]) -> usize
|
where F: FnOnce(&mut [c_char]) -> usize
|
||||||
{
|
{
|
||||||
|
|
@ -193,7 +178,7 @@ impl PKey {
|
||||||
unsafe {
|
unsafe {
|
||||||
let evp = try!(cvt_p(ffi::PEM_read_bio_PrivateKey(mem_bio.as_ptr(),
|
let evp = try!(cvt_p(ffi::PEM_read_bio_PrivateKey(mem_bio.as_ptr(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
Some(invoke_passwd_cb::<F>),
|
Some(invoke_passwd_cb_old::<F>),
|
||||||
&mut cb as *mut _ as *mut c_void)));
|
&mut cb as *mut _ as *mut c_void)));
|
||||||
Ok(PKey::from_ptr(evp))
|
Ok(PKey::from_ptr(evp))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use {cvt, cvt_p, cvt_n};
|
||||||
use bn::{BigNum, BigNumRef};
|
use bn::{BigNum, BigNumRef};
|
||||||
use bio::{MemBio, MemBioSlice};
|
use bio::{MemBio, MemBioSlice};
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use util::{CallbackState, invoke_passwd_cb};
|
use util::{CallbackState, invoke_passwd_cb_old};
|
||||||
use types::OpenSslTypeRef;
|
use types::OpenSslTypeRef;
|
||||||
|
|
||||||
/// Type of encryption padding to use.
|
/// Type of encryption padding to use.
|
||||||
|
|
@ -281,20 +281,9 @@ impl Rsa {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads an RSA private key from PEM formatted data.
|
private_key_from_pem!(Rsa, ffi::PEM_read_bio_RSAPrivateKey);
|
||||||
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(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
None,
|
|
||||||
ptr::null_mut())));
|
|
||||||
Ok(Rsa(rsa))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an RSA private key from PEM formatted data and supplies a password callback.
|
#[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")]
|
||||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
|
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<Rsa, ErrorStack>
|
||||||
where F: FnOnce(&mut [c_char]) -> usize
|
where F: FnOnce(&mut [c_char]) -> usize
|
||||||
{
|
{
|
||||||
|
|
@ -306,7 +295,7 @@ impl Rsa {
|
||||||
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
||||||
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(),
|
let rsa = try!(cvt_p(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.as_ptr(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
Some(invoke_passwd_cb::<F>),
|
Some(invoke_passwd_cb_old::<F>),
|
||||||
cb_ptr)));
|
cb_ptr)));
|
||||||
Ok(Rsa(rsa))
|
Ok(Rsa(rsa))
|
||||||
}
|
}
|
||||||
|
|
@ -429,22 +418,15 @@ mod compat {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use libc::c_char;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_password() {
|
pub fn test_password() {
|
||||||
let mut password_queried = false;
|
let mut password_queried = false;
|
||||||
let key = include_bytes!("../test/rsa-encrypted.pem");
|
let key = include_bytes!("../test/rsa-encrypted.pem");
|
||||||
Rsa::private_key_from_pem_cb(key, |password| {
|
Rsa::private_key_from_pem_callback(key, |password| {
|
||||||
password_queried = true;
|
password_queried = true;
|
||||||
password[0] = b'm' as c_char;
|
password[..6].copy_from_slice(b"mypass");
|
||||||
password[1] = b'y' as c_char;
|
|
||||||
password[2] = b'p' as c_char;
|
|
||||||
password[3] = b'a' as c_char;
|
|
||||||
password[4] = b's' as c_char;
|
|
||||||
password[5] = b's' as c_char;
|
|
||||||
6
|
6
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,7 @@ impl<F> Drop for CallbackState<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Password callback function, passed to private key loading functions.
|
pub unsafe extern fn invoke_passwd_cb_old<F>(buf: *mut c_char,
|
||||||
///
|
|
||||||
/// `cb_state` is expected to be a pointer to a `CallbackState`.
|
|
||||||
pub unsafe extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char,
|
|
||||||
size: c_int,
|
size: c_int,
|
||||||
_rwflag: c_int,
|
_rwflag: c_int,
|
||||||
cb_state: *mut c_void)
|
cb_state: *mut c_void)
|
||||||
|
|
@ -46,9 +43,33 @@ pub unsafe extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char,
|
||||||
let callback = &mut *(cb_state as *mut CallbackState<F>);
|
let callback = &mut *(cb_state as *mut CallbackState<F>);
|
||||||
|
|
||||||
let result = panic::catch_unwind(AssertUnwindSafe(|| {
|
let result = panic::catch_unwind(AssertUnwindSafe(|| {
|
||||||
// build a `i8` slice to pass to the user callback
|
|
||||||
let pass_slice = slice::from_raw_parts_mut(buf, size as usize);
|
let pass_slice = slice::from_raw_parts_mut(buf, size as usize);
|
||||||
|
callback.cb.take().unwrap()(pass_slice)
|
||||||
|
}));
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(len) => len as c_int,
|
||||||
|
Err(err) => {
|
||||||
|
callback.panic = Some(err);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Password callback function, passed to private key loading functions.
|
||||||
|
///
|
||||||
|
/// `cb_state` is expected to be a pointer to a `CallbackState`.
|
||||||
|
pub unsafe extern fn invoke_passwd_cb<F>(buf: *mut c_char,
|
||||||
|
size: c_int,
|
||||||
|
_rwflag: c_int,
|
||||||
|
cb_state: *mut c_void)
|
||||||
|
-> c_int
|
||||||
|
where F: FnOnce(&mut [u8]) -> usize
|
||||||
|
{
|
||||||
|
let callback = &mut *(cb_state as *mut CallbackState<F>);
|
||||||
|
|
||||||
|
let result = panic::catch_unwind(AssertUnwindSafe(|| {
|
||||||
|
let pass_slice = slice::from_raw_parts_mut(buf as *mut u8, size as usize);
|
||||||
callback.cb.take().unwrap()(pass_slice)
|
callback.cb.take().unwrap()(pass_slice)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue