327 lines
9.4 KiB
Rust
327 lines
9.4 KiB
Rust
// 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 secp256k1::SecretKey;
|
||
use wallet_impl::Wallet;
|
||
|
||
use crate::wallet::*;
|
||
mod utils;
|
||
use utils::crypto_utils::{
|
||
general_rsa_keystr, 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 = unsafe {CStr::from_ptr($p1)};
|
||
let ps = match s.to_str(){
|
||
Err(err) => panic!("Problem convert c_char to string: {:?}", err),
|
||
Ok(string) => string,
|
||
};
|
||
ps
|
||
}};
|
||
}
|
||
|
||
macro_rules! cchar_to_string {
|
||
($p1:expr) => {{
|
||
let s = unsafe {CStr::from_ptr($p1)};
|
||
let ps = match s.to_str() {
|
||
Err(err) => panic!("Problem convert c_char to string: {:?}", err),
|
||
Ok(string) => string,
|
||
};
|
||
ps.to_string()
|
||
}};
|
||
}
|
||
|
||
macro_rules! str_to_cchar {
|
||
($p1:expr) => {{
|
||
let msgkey = CString::new($p1).unwrap();
|
||
msgkey.into_raw()
|
||
}};
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub 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 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 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 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 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 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 extern "C" fn rdecrypt(sk: *const c_char, msg: *const c_char) -> *mut c_char {
|
||
let msg_str = cchar_to_str!(msg);
|
||
let sk_str = cchar_to_str!(sk);
|
||
let private_key = match SecretKey::from_str(sk_str) {
|
||
Ok(v) => v,
|
||
Err(e) => panic!("error parse publickey: {}", e),
|
||
};
|
||
let msg_encrypt = match zdecrypt(private_key, msg_str) {
|
||
Ok(v) => v,
|
||
Err(err) => panic!("error encrypt: {:?}", err),
|
||
};
|
||
str_to_cchar!(msg_encrypt)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub 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 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 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 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 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 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 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 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 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 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 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)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern "C" fn simple_sign(content: *const c_char, key: *const c_char) -> *mut c_char {
|
||
let result = wallet_impl::simple_sign(cchar_to_str!(content), cchar_to_str!(key));
|
||
let r = match result {
|
||
Ok(v) => v,
|
||
Err(err) => panic!("Problem sign: {:?}", err),
|
||
};
|
||
str_to_cchar!(r)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern "C" fn ramdonKey() -> *mut c_char {
|
||
let (s_key, _p_key) = wallet_impl::generate_keypair();
|
||
let s_key = hex::encode(&s_key.secret_bytes());
|
||
let cs_key = CString::new(s_key).unwrap();
|
||
cs_key.into_raw()
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern "C" fn rsa_key_pair() -> *mut c_char {
|
||
let key_str = general_rsa_keystr();
|
||
return str_to_cchar!(key_str);
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern "C" fn rsa_encrypt(content: *const c_char, p_key: *const c_char) -> *mut c_char {
|
||
let content_str = cchar_to_str!(content);
|
||
let p_key_str = cchar_to_str!(p_key);
|
||
let msg_encrypt = utils::crypto_utils::rsa_encrypt(content_str, p_key_str);
|
||
str_to_cchar!(msg_encrypt)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern "C" fn rsa_decrypt(content: *const c_char, s_key: *const c_char) -> *mut c_char {
|
||
let content_str = cchar_to_str!(content);
|
||
let s_key_str = cchar_to_str!(s_key);
|
||
let msg_decrypt = utils::crypto_utils::rsa_decrypt(content_str, s_key_str);
|
||
str_to_cchar!(msg_decrypt)
|
||
}
|
||
|
||
#[no_mangle]
|
||
pub extern fn free_cstr(s: *mut c_char) {
|
||
unsafe {
|
||
if s.is_null() { return }
|
||
CString::from_raw(s)
|
||
};
|
||
}
|
||
|
||
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,
|
||
}
|
||
}
|