1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn;
#[proc_macro_derive(MpesaSecurity)]
pub fn mpesa_security_derive(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).expect("Error parsing input");
impl_mpesa_security(&ast)
}
fn impl_mpesa_security(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let gen = quote! {
use openssl::x509::X509;
use openssl::rsa::Padding;
use base64::encode;
use std::error::Error;
use mpesa::MpesaError;
impl MpesaSecurity for #name {
fn gen_security_credentials(&self) -> Result<String, MpesaError> {
let pem = self.environment.get_certificate().as_bytes();
let cert = X509::from_pem(pem)?;
let pub_key = cert.public_key()?;
let rsa_key = pub_key.rsa()?;
let buf_len = pub_key.size();
let mut buffer = vec![0; buf_len];
rsa_key.public_encrypt(
self.initiator_password(),
&mut buffer,
Padding::PKCS1,
)?;
Ok(encode(buffer))
}
}
};
gen.into()
}