rustwallet/src/lib.rs

260 lines
6.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// lib.rs
//
// 此部分代码主要负责Rust-C两侧的数据内存结构转换提供了C侧的函数接口。注意命名规范
// 在C侧使用时凡是函数名带有 '_cwallet'的,调用过之后都必须用'free_cwallet'释放内存,
// 否则导致内存泄漏
//
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
mod wallet;
use wallet_impl::Wallet;
use crate::wallet::*;
mod utils;
use utils::str_utils::{base64_to_hex, hex_to_base64};
// #[cfg(target_os = "android")]
// mod android;
macro_rules! cchar_to_str{
($p1:expr) => {
{
let s = CStr::from_ptr($p1);
let ps = s.to_str().unwrap();
ps
}
}
}
macro_rules! cchar_to_string{
($p1:expr) => {
{
let s = CStr::from_ptr($p1);
let ps = s.to_str().unwrap();
ps.to_string()
}
}
}
macro_rules! cchar_to_ostring{
($p1:expr) => {
{
let s = CStr::from_ptr($p1);
let pb = s.to_str().unwrap();
let result = if pb.is_empty() {
None
} else {
Some(pb.to_string())
};
result
}
}
}
macro_rules! str_to_cchar {
($p1:expr) => {
{
let msgkey = CString::new($p1).unwrap();
let c_msgkey: *mut c_char = msgkey.into_raw();
c_msgkey
}
};
}
macro_rules! ostr_to_cchar{
($p1:expr) => {
{
let key = match $p1 {
Some(val) => {
CString::new(val).unwrap()
},
None => CString::new("").unwrap()
};
let c_key: *mut c_char = key.into_raw();
c_key
}
}
}
#[repr(C)]
pub struct CWallet {
pub msg_key: *mut c_char,
pub master_key: *mut c_char,
pub second_key: *mut c_char,
pub backup_key: *mut c_char,
}
#[no_mangle]
pub unsafe extern "C" fn new_wallet(msg: *const c_char) -> CWallet {
let str = cchar_to_str!(msg);
let rust_wallet = wallet_impl::Wallet::new(str);
convert_to_cwallet(rust_wallet)
}
#[no_mangle]
pub unsafe extern "C" fn reset_wallet(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
) -> CWallet {
let rust_wallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let rust_wallet2 = rust_wallet.reset_wallet();
convert_to_cwallet(rust_wallet2)
}
#[no_mangle]
pub unsafe extern "C" fn free_cwallet(cw: CWallet) {
drop(CString::from_raw(cw.msg_key));
drop(CString::from_raw(cw.master_key));
drop(CString::from_raw(cw.second_key));
drop(CString::from_raw(cw.backup_key));
}
#[no_mangle]
pub unsafe extern "C" fn get_address(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
) -> *mut c_char{
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let address = rwallet.get_address();
let address_str = format!("{:?}", address);
let c_address = CString::new(address_str).unwrap();
c_address.into_raw()
}
#[no_mangle]
pub unsafe extern "C" fn generate_sec_key(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let s_key = rwallet.generate_sec_key();
let cs_key = CString::new(s_key).unwrap();
cs_key.into_raw()
}
#[no_mangle]
pub unsafe extern "C" fn sign(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
msg: *const c_char
) -> *mut c_char{
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let msg_str = cchar_to_str!(msg);
let signature = rwallet.sign(msg_str);
let r = match signature {
Ok(v) => v,
Err(err) => panic!("Problem sign: {:?}", err),
};
str_to_cchar!(r)
}
#[no_mangle]
pub unsafe extern "C" fn sign_for_tran(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
msg: *const c_char
) -> *mut c_char{
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let msg_str = cchar_to_str!(msg);
let signature = rwallet.sign_for_tran(msg_str);
let (r, recid) = match signature {
Ok((v, _recid)) => (v, _recid),
Err(err) => panic!("Problem sign: {:?}", err),
};
let result = format!("{}|{}", r, recid);
str_to_cchar!(result)
}
#[no_mangle]
pub unsafe extern "C" fn rencrypt(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
msg: *const c_char
) -> *mut c_char{
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let msg_str = cchar_to_str!(msg);
let msg_encrypt = match rwallet.zencrypt(msg_str){
Ok(v) => v,
Err(err) => panic!("error encrypt: {:?}", err),
};
str_to_cchar!(msg_encrypt)
}
#[no_mangle]
pub unsafe extern "C" fn rdecrypt(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
msg: *const c_char
) -> *mut c_char{
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
let msg_str = cchar_to_str!(msg);
let msg_decrypt = match rwallet.zdecrypt(msg_str){
Ok(v) => v,
Err(err) => panic!("error decrypt: {:?}", err),
};
str_to_cchar!(msg_decrypt)
}
#[no_mangle]
pub unsafe extern "C" fn str_deflate(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let msg_base64 = hex_to_base64(&content_str);
str_to_cchar!(msg_base64)
}
#[no_mangle]
pub unsafe extern "C" fn str_inflate(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let msg_hex = base64_to_hex(&content_str);
str_to_cchar!(msg_hex)
}
unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet {
let c_msgkey: *mut c_char = str_to_cchar!(rwallet.msg_key);
let c_masterkey: *mut c_char = str_to_cchar!(rwallet.master_key);
let c_secondkey = ostr_to_cchar!(rwallet.second_key);
let c_backupkey = ostr_to_cchar!(rwallet.backup_key);
let cw = CWallet {
msg_key: c_msgkey,
master_key: c_masterkey,
second_key: c_secondkey,
backup_key: c_backupkey,
};
cw
}
unsafe fn generate_rwallet(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
backup_key: *const c_char,
) ->Wallet {
let pmsg = cchar_to_string!(msg_key);
let pm = cchar_to_string!(master_key);
let second_key = cchar_to_ostring!(second_key);
let backup_key = cchar_to_ostring!(backup_key);
Wallet {
msg_key: pmsg,
master_key: pm,
second_key: second_key,
backup_key: backup_key
}
}