use crate::client::MpesaResult;
use crate::Mpesa;
use base64::encode;
use openssl::rsa::Padding;
use openssl::x509::X509;
/// Trait responsible for implementation of security configs for Mpesa
pub trait MpesaSecurity {
/// Generates security credentials
/// M-Pesa Core authenticates a transaction by decrypting the security credentials.
/// Security credentials are generated by encrypting the base64 encoded initiator password with M-Pesa’s public key, a X509 certificate.
/// Returns base64 encoded string.
///
/// # Error
/// Returns `EncryptionError` variant of `MpesaError`
fn gen_security_credentials(&self) -> MpesaResult<String>;
}
impl MpesaSecurity for Mpesa {
fn gen_security_credentials(&self) -> MpesaResult<String> {
let pem = self.environment().get_certificate().as_bytes();
let cert = X509::from_pem(pem)?;
// getting the public and rsa keys
let pub_key = cert.public_key()?;
let rsa_key = pub_key.rsa()?;
// configuring the buffer
let buf_len = pub_key.size();
let mut buffer = vec![0; buf_len];
rsa_key.public_encrypt(
self.initiator_password().as_bytes(),
&mut buffer,
Padding::PKCS1,
)?;
Ok(encode(buffer))
}
}