use crate::utils::*;
use botan_sys::*;
use crate::pubkey::{Privkey, Pubkey};
use crate::rng::RandomNumberGenerator;
#[derive(Debug)]
pub struct Signer {
obj: botan_pk_op_sign_t,
sig_len: usize,
}
unsafe impl Sync for Signer {}
unsafe impl Send for Signer {}
botan_impl_drop!(Signer, botan_pk_op_sign_destroy);
impl Signer {
pub fn new<P: crate::SignatureParamsIdentifier>(key: &Privkey, padding: P) -> Result<Signer> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_sign_create,
key.handle(),
padding.as_ptr(),
0u32
)?;
let sig_len = botan_usize!(botan_pk_op_sign_output_length, obj)?;
Ok(Signer { obj, sig_len })
}
pub fn new_with_der_formatted_signatures<P: crate::SignatureParamsIdentifier>(
key: &Privkey,
padding: P,
) -> Result<Signer> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_sign_create,
key.handle(),
padding.as_ptr(),
1u32
)?;
let sig_len = botan_usize!(botan_pk_op_sign_output_length, obj)?;
Ok(Signer { obj, sig_len })
}
pub fn signature_length(&self) -> usize {
self.sig_len
}
pub fn update(&mut self, data: &[u8]) -> Result<()> {
botan_call!(botan_pk_op_sign_update, self.obj, data.as_ptr(), data.len())
}
pub fn finish(&mut self, rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
let rng_handle = rng.handle();
call_botan_ffi_returning_vec_u8(self.sig_len, &|out_buf, out_len| unsafe {
botan_pk_op_sign_finish(self.obj, rng_handle, out_buf, out_len)
})
}
}
#[derive(Debug)]
pub struct Decryptor {
obj: botan_pk_op_decrypt_t,
}
unsafe impl Sync for Decryptor {}
unsafe impl Send for Decryptor {}
botan_impl_drop!(Decryptor, botan_pk_op_decrypt_destroy);
impl Decryptor {
pub fn new<P: crate::EncryptionParamsIdentifier>(
key: &Privkey,
padding: P,
) -> Result<Decryptor> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_decrypt_create,
key.handle(),
padding.as_ptr(),
0u32
)?;
Ok(Decryptor { obj })
}
pub fn decrypt(&mut self, ctext: &[u8]) -> Result<Vec<u8>> {
let mut ptext_len = 0;
botan_call!(
botan_pk_op_decrypt_output_length,
self.obj,
ctext.len(),
&mut ptext_len
)?;
call_botan_ffi_returning_vec_u8(ptext_len, &|out_buf, out_len| unsafe {
botan_pk_op_decrypt(self.obj, out_buf, out_len, ctext.as_ptr(), ctext.len())
})
}
}
#[derive(Debug)]
pub struct Verifier {
obj: botan_pk_op_verify_t,
}
unsafe impl Sync for Verifier {}
unsafe impl Send for Verifier {}
botan_impl_drop!(Verifier, botan_pk_op_verify_destroy);
impl Verifier {
pub fn new<P: crate::SignatureParamsIdentifier>(key: &Pubkey, padding: P) -> Result<Verifier> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_verify_create,
key.handle(),
padding.as_ptr(),
0u32
)?;
Ok(Verifier { obj })
}
pub fn new_with_der_formatted_signatures<P: crate::SignatureParamsIdentifier>(
key: &Pubkey,
padding: P,
) -> Result<Verifier> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_verify_create,
key.handle(),
padding.as_ptr(),
1u32
)?;
Ok(Verifier { obj })
}
pub fn update(&mut self, data: &[u8]) -> Result<()> {
botan_call!(
botan_pk_op_verify_update,
self.obj,
data.as_ptr(),
data.len()
)
}
pub fn finish(&mut self, signature: &[u8]) -> Result<bool> {
match unsafe { botan_pk_op_verify_finish(self.obj, signature.as_ptr(), signature.len()) } {
0 => Ok(true),
BOTAN_FFI_INVALID_VERIFIER => Ok(false),
e => Err(Error::from_rc(e)),
}
}
}
#[derive(Debug)]
pub struct Encryptor {
obj: botan_pk_op_encrypt_t,
}
unsafe impl Sync for Encryptor {}
unsafe impl Send for Encryptor {}
botan_impl_drop!(Encryptor, botan_pk_op_encrypt_destroy);
impl Encryptor {
pub fn new<P: crate::EncryptionParamsIdentifier>(
key: &Pubkey,
padding: P,
) -> Result<Encryptor> {
key.check_op_supported()?;
let padding = padding.botan_name();
let padding = make_cstr(&padding)?;
let obj = botan_init!(
botan_pk_op_encrypt_create,
key.handle(),
padding.as_ptr(),
0u32
)?;
Ok(Encryptor { obj })
}
pub fn encrypt(&mut self, ptext: &[u8], rng: &mut RandomNumberGenerator) -> Result<Vec<u8>> {
let mut ctext_len = 0;
botan_call!(
botan_pk_op_encrypt_output_length,
self.obj,
ptext.len(),
&mut ctext_len
)?;
let rng_handle = rng.handle();
call_botan_ffi_returning_vec_u8(ctext_len, &|out_buf, out_len| unsafe {
botan_pk_op_encrypt(
self.obj,
rng_handle,
out_buf,
out_len,
ptext.as_ptr(),
ptext.len(),
)
})
}
}
#[derive(Debug)]
pub struct KeyAgreement {
obj: botan_pk_op_ka_t,
}
unsafe impl Sync for KeyAgreement {}
unsafe impl Send for KeyAgreement {}
botan_impl_drop!(KeyAgreement, botan_pk_op_key_agreement_destroy);
impl KeyAgreement {
pub fn new<K: crate::KdfAlgorithmIdentifier>(key: &Privkey, kdf: K) -> Result<KeyAgreement> {
key.check_op_supported()?;
let kdf = kdf.botan_name();
let kdf = make_cstr(&kdf)?;
let obj = botan_init!(
botan_pk_op_key_agreement_create,
key.handle(),
kdf.as_ptr(),
0u32
)?;
Ok(KeyAgreement { obj })
}
pub fn agree(
&mut self,
requested_output: usize,
counterparty_key: &[u8],
salt: &[u8],
) -> Result<Vec<u8>> {
let mut ka_len = requested_output;
if ka_len == 0 {
ka_len = botan_usize!(botan_pk_op_key_agreement_size, self.obj)?;
}
call_botan_ffi_returning_vec_u8(ka_len, &|out_buf, out_len| unsafe {
botan_pk_op_key_agreement(
self.obj,
out_buf,
out_len,
counterparty_key.as_ptr(),
counterparty_key.len(),
salt.as_ptr(),
salt.len(),
)
})
}
}