// 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, } }