417 lines
14 KiB
Rust
417 lines
14 KiB
Rust
use rhai::{Engine, Scope, Dynamic, FnPtr};
|
|
use webassembly::core::keypair;
|
|
use webassembly::core::symmetric;
|
|
use webassembly::core::ethereum;
|
|
use webassembly::core::error::CryptoError;
|
|
use std::str::FromStr;
|
|
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
|
|
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
// Key space management functions
|
|
fn load_key_space(name: &str, password: &str) -> bool {
|
|
// Get the key spaces directory from config
|
|
let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
let key_spaces_dir = home_dir.join(".hero-vault").join("key-spaces");
|
|
|
|
// Check if directory exists
|
|
if !key_spaces_dir.exists() {
|
|
println!("Key spaces directory does not exist");
|
|
return false;
|
|
}
|
|
|
|
// Get the key space file path
|
|
let space_path = key_spaces_dir.join(format!("{}.json", name));
|
|
|
|
// Check if file exists
|
|
if !space_path.exists() {
|
|
println!("Key space file not found: {}", space_path.display());
|
|
return false;
|
|
}
|
|
|
|
// Read the file
|
|
let serialized = match fs::read_to_string(&space_path) {
|
|
Ok(data) => data,
|
|
Err(e) => {
|
|
println!("Error reading key space file: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Deserialize the encrypted space
|
|
let encrypted_space = match symmetric::deserialize_encrypted_space(&serialized) {
|
|
Ok(space) => space,
|
|
Err(e) => {
|
|
println!("Error deserializing key space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Decrypt the space
|
|
let space = match symmetric::decrypt_key_space(&encrypted_space, password) {
|
|
Ok(space) => space,
|
|
Err(e) => {
|
|
println!("Error decrypting key space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Set as current space
|
|
match keypair::set_current_space(space) {
|
|
Ok(_) => true,
|
|
Err(e) => {
|
|
println!("Error setting current space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
fn create_key_space(name: &str, password: &str) -> bool {
|
|
match keypair::create_space(name) {
|
|
Ok(_) => {
|
|
// Get the current space
|
|
match keypair::get_current_space() {
|
|
Ok(space) => {
|
|
// Encrypt the key space
|
|
let encrypted_space = match symmetric::encrypt_key_space(&space, password) {
|
|
Ok(encrypted) => encrypted,
|
|
Err(e) => {
|
|
println!("Error encrypting key space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Serialize the encrypted space
|
|
let serialized = match symmetric::serialize_encrypted_space(&encrypted_space) {
|
|
Ok(json) => json,
|
|
Err(e) => {
|
|
println!("Error serializing encrypted space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Get the key spaces directory
|
|
let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
let key_spaces_dir = home_dir.join(".hero-vault").join("key-spaces");
|
|
|
|
// Create directory if it doesn't exist
|
|
if !key_spaces_dir.exists() {
|
|
match fs::create_dir_all(&key_spaces_dir) {
|
|
Ok(_) => {},
|
|
Err(e) => {
|
|
println!("Error creating key spaces directory: {}", e);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write to file
|
|
let space_path = key_spaces_dir.join(format!("{}.json", name));
|
|
match fs::write(&space_path, serialized) {
|
|
Ok(_) => {
|
|
println!("Key space created and saved to {}", space_path.display());
|
|
true
|
|
},
|
|
Err(e) => {
|
|
println!("Error writing key space file: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error getting current space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error creating key space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
// Auto-save function for internal use
|
|
fn auto_save_key_space(password: &str) -> bool {
|
|
match keypair::get_current_space() {
|
|
Ok(space) => {
|
|
// Encrypt the key space
|
|
let encrypted_space = match symmetric::encrypt_key_space(&space, password) {
|
|
Ok(encrypted) => encrypted,
|
|
Err(e) => {
|
|
println!("Error encrypting key space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Serialize the encrypted space
|
|
let serialized = match symmetric::serialize_encrypted_space(&encrypted_space) {
|
|
Ok(json) => json,
|
|
Err(e) => {
|
|
println!("Error serializing encrypted space: {}", e);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Get the key spaces directory
|
|
let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
|
|
let key_spaces_dir = home_dir.join(".hero-vault").join("key-spaces");
|
|
|
|
// Create directory if it doesn't exist
|
|
if !key_spaces_dir.exists() {
|
|
match fs::create_dir_all(&key_spaces_dir) {
|
|
Ok(_) => {},
|
|
Err(e) => {
|
|
println!("Error creating key spaces directory: {}", e);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write to file
|
|
let space_path = key_spaces_dir.join(format!("{}.json", space.name));
|
|
match fs::write(&space_path, serialized) {
|
|
Ok(_) => {
|
|
println!("Key space saved to {}", space_path.display());
|
|
true
|
|
},
|
|
Err(e) => {
|
|
println!("Error writing key space file: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error getting current space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
fn encrypt_key_space(password: &str) -> String {
|
|
match keypair::get_current_space() {
|
|
Ok(space) => {
|
|
match symmetric::encrypt_key_space(&space, password) {
|
|
Ok(encrypted_space) => {
|
|
match serde_json::to_string(&encrypted_space) {
|
|
Ok(json) => json,
|
|
Err(e) => {
|
|
println!("Error serializing encrypted space: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error encrypting key space: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error getting current space: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
|
|
match serde_json::from_str(encrypted) {
|
|
Ok(encrypted_space) => {
|
|
match symmetric::decrypt_key_space(&encrypted_space, password) {
|
|
Ok(space) => {
|
|
match keypair::set_current_space(space) {
|
|
Ok(_) => true,
|
|
Err(e) => {
|
|
println!("Error setting current space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decrypting key space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error parsing encrypted space: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
// Keypair management functions
|
|
fn create_keypair(name: &str, password: &str) -> bool {
|
|
match keypair::create_keypair(name) {
|
|
Ok(_) => {
|
|
// Auto-save the key space after creating a keypair
|
|
auto_save_key_space(password)
|
|
},
|
|
Err(e) => {
|
|
println!("Error creating keypair: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
fn select_keypair(name: &str) -> bool {
|
|
match keypair::select_keypair(name) {
|
|
Ok(_) => true,
|
|
Err(e) => {
|
|
println!("Error selecting keypair: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
fn list_keypairs() -> Vec<String> {
|
|
match keypair::list_keypairs() {
|
|
Ok(keypairs) => keypairs,
|
|
Err(e) => {
|
|
println!("Error listing keypairs: {}", e);
|
|
Vec::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cryptographic operations
|
|
fn sign(message: &str) -> String {
|
|
let message_bytes = message.as_bytes();
|
|
match keypair::keypair_sign(message_bytes) {
|
|
Ok(signature) => BASE64.encode(signature),
|
|
Err(e) => {
|
|
println!("Error signing message: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn verify(message: &str, signature: &str) -> bool {
|
|
let message_bytes = message.as_bytes();
|
|
match BASE64.decode(signature) {
|
|
Ok(signature_bytes) => {
|
|
match keypair::keypair_verify(message_bytes, &signature_bytes) {
|
|
Ok(is_valid) => is_valid,
|
|
Err(e) => {
|
|
println!("Error verifying signature: {}", e);
|
|
false
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decoding signature: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
// Symmetric encryption
|
|
fn generate_key() -> String {
|
|
let key = symmetric::generate_symmetric_key();
|
|
BASE64.encode(key)
|
|
}
|
|
|
|
fn encrypt(key: &str, message: &str) -> String {
|
|
match BASE64.decode(key) {
|
|
Ok(key_bytes) => {
|
|
let message_bytes = message.as_bytes();
|
|
match symmetric::encrypt_symmetric(&key_bytes, message_bytes) {
|
|
Ok(ciphertext) => BASE64.encode(ciphertext),
|
|
Err(e) => {
|
|
println!("Error encrypting message: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decoding key: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
fn decrypt(key: &str, ciphertext: &str) -> String {
|
|
match BASE64.decode(key) {
|
|
Ok(key_bytes) => {
|
|
match BASE64.decode(ciphertext) {
|
|
Ok(ciphertext_bytes) => {
|
|
match symmetric::decrypt_symmetric(&key_bytes, &ciphertext_bytes) {
|
|
Ok(plaintext) => {
|
|
match String::from_utf8(plaintext) {
|
|
Ok(text) => text,
|
|
Err(e) => {
|
|
println!("Error converting plaintext to string: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decrypting ciphertext: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decoding ciphertext: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Error decoding key: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ethereum operations
|
|
fn create_ethereum_wallet() -> bool {
|
|
match ethereum::create_ethereum_wallet() {
|
|
Ok(_) => true,
|
|
Err(e) => {
|
|
println!("Error creating Ethereum wallet: {}", e);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_ethereum_address() -> String {
|
|
match ethereum::get_current_ethereum_wallet() {
|
|
Ok(wallet) => wallet.address_string(),
|
|
Err(e) => {
|
|
println!("Error getting Ethereum address: {}", e);
|
|
String::new()
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn register_crypto_api(engine: &mut Engine, scope: &mut Scope<'_>) {
|
|
// Register key space functions
|
|
engine.register_fn("load_key_space", load_key_space);
|
|
engine.register_fn("create_key_space", create_key_space);
|
|
engine.register_fn("encrypt_key_space", encrypt_key_space);
|
|
engine.register_fn("decrypt_key_space", decrypt_key_space);
|
|
|
|
// Register keypair functions
|
|
engine.register_fn("create_keypair", create_keypair);
|
|
engine.register_fn("select_keypair", select_keypair);
|
|
engine.register_fn("list_keypairs", list_keypairs);
|
|
|
|
// Register signing/verification functions
|
|
engine.register_fn("sign", sign);
|
|
engine.register_fn("verify", verify);
|
|
|
|
// Register symmetric encryption functions
|
|
engine.register_fn("generate_key", generate_key);
|
|
engine.register_fn("encrypt", encrypt);
|
|
engine.register_fn("decrypt", decrypt);
|
|
|
|
// Register Ethereum functions
|
|
engine.register_fn("create_ethereum_wallet", create_ethereum_wallet);
|
|
engine.register_fn("get_ethereum_address", get_ethereum_address);
|
|
|
|
// Add any additional functions or variables to the scope
|
|
scope.push("VERSION", "1.0.0");
|
|
}
|