rustwallet/src/lib.rs
2024-01-25 19:02:13 +08:00

327 lines
9.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 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,
}
}