rustwallet/src/lib.rs
2023-05-10 19:14:02 +08:00

256 lines
7.4 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;
use std::str::FromStr;
mod wallet;
use secp256k1::PublicKey;
use wallet_impl::Wallet;
use crate::wallet::*;
mod utils;
use utils::crypto_utils::{zdecrypt, zencrypt};
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! str_to_cchar {
($p1:expr) => {{
let msgkey = CString::new($p1).unwrap();
let c_msgkey: *mut c_char = msgkey.into_raw();
c_msgkey
}};
}
#[no_mangle]
pub unsafe extern "C" fn get_address(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_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 get_public_key(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key);
let pk = rwallet.get_public_key();
let c_pk = CString::new(pk.to_string()).unwrap();
c_pk.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,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_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,
msg: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_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,
msg: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key);
let msg_str = cchar_to_str!(msg);
println!("msg for sign tran: {}", &msg_str);
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(pk: *const c_char, msg: *const c_char) -> *mut c_char {
let msg_str = cchar_to_str!(msg);
let pk_str = cchar_to_str!(pk);
let public_key = match PublicKey::from_str(pk_str) {
Ok(v) => v,
Err(e) => panic!("error parse publickey: {}", e),
};
let msg_encrypt = match zencrypt(public_key, msg_str) {
Ok(v) => v,
Err(err) => panic!("error encrypt: {:?}", err),
};
str_to_cchar!(msg_encrypt)
}
#[no_mangle]
pub unsafe extern "C" fn wallet_encrypt(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
msg: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key);
let msg_str = cchar_to_str!(msg);
let pk = rwallet.get_public_key();
let msg_encrypt = match zencrypt(pk, msg_str) {
Ok(v) => v,
Err(err) => panic!("error encrypt: {:?}", err),
};
str_to_cchar!(msg_encrypt)
}
#[no_mangle]
pub unsafe extern "C" fn wallet_decrypt(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
msg: *const c_char,
) -> *mut c_char {
let rwallet = generate_rwallet(msg_key, master_key, second_key);
let msg_str = cchar_to_str!(msg);
let sk = rwallet.get_secret_key();
let msg_decrypt = match zdecrypt(sk, msg_str) {
Ok(v) => v,
Err(err) => panic!("error decrypt: {:?}", err),
};
str_to_cchar!(msg_decrypt)
}
#[no_mangle]
pub unsafe extern "C" fn hex_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 hex_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)
}
// hash pasword of email register
#[no_mangle]
pub unsafe extern "C" fn hash_pass_svr(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let msg_hex = utils::crypto_utils::hash_pass_svr(&content_str);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn keccak256_hash(content: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let msg_hex = utils::crypto_utils::keccak256_hash(&content_str);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn aes_encrypt(content: *const c_char, key: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let pass = cchar_to_str!(key);
let pass = utils::crypto_utils::keccak256_hash(pass);
let msg_hex = utils::crypto_utils::aes_encrypt(&content_str, &pass);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn aes_decrypt(content: *const c_char, key: *const c_char) -> *mut c_char {
let content_str = cchar_to_str!(content);
let pass = cchar_to_str!(key);
let pass = utils::crypto_utils::keccak256_hash(pass);
let msg_hex = utils::crypto_utils::aes_decrypt(&content_str, &pass);
str_to_cchar!(msg_hex)
}
#[no_mangle]
pub unsafe extern "C" fn local_pass_hasher(password: *const c_char) -> *mut c_char {
let result = wallet_impl::local_pass_hasher(cchar_to_str!(password));
str_to_cchar!(result)
}
#[no_mangle]
pub unsafe extern "C" fn verify_local_pass(
password: *const c_char,
pass_hash: *const c_char,
) -> bool {
utils::crypto_utils::verify_password(cchar_to_str!(password), cchar_to_str!(pass_hash))
}
#[no_mangle]
pub unsafe extern "C" fn generate_client_key(
password: *const c_char,
openid: *const c_char,
salt: *const c_char,
) -> *mut c_char {
let result = wallet_impl::generate_client_key(
cchar_to_str!(password),
cchar_to_str!(openid),
cchar_to_str!(salt),
);
str_to_cchar!(result)
}
unsafe fn generate_rwallet(
msg_key: *const c_char,
master_key: *const c_char,
second_key: *const c_char,
) -> Wallet {
let pmsg = cchar_to_string!(msg_key);
let pm = cchar_to_string!(master_key);
let second_key = cchar_to_string!(second_key);
Wallet {
msg_key: pmsg,
master_key: pm,
second_key: second_key,
}
}