tests & fixes in kvs & keypair

This commit is contained in:
despiegk 2025-05-13 06:45:04 +03:00
parent 3a0900fc15
commit 3f8aecb786
12 changed files with 343 additions and 21 deletions

View File

@ -21,7 +21,7 @@ env_logger = "0.10.0" # Logger implementation
ethers = { version = "2.0.7", features = ["legacy"] } # Ethereum library
glob = "0.3.1" # For file pattern matching
jsonrpsee = "0.25.1"
k256 = { version = "0.13.1", features = ["ecdsa"] } # Elliptic curve cryptography
k256 = { version = "0.13.1", features = ["ecdsa", "ecdh"] } # Elliptic curve cryptography
lazy_static = "1.4.0" # For lazy initialization of static variables
libc = "0.2"
log = "0.4" # Logging facade

View File

@ -214,18 +214,16 @@ impl KeyPair {
let ephemeral_signing_key = SigningKey::random(&mut OsRng);
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
// Derive shared secret (this is a simplified ECDH)
// In a real implementation, we would use proper ECDH, but for this example:
let shared_point = recipient_key.to_encoded_point(false);
let shared_secret = {
let mut hasher = Sha256::default();
hasher.update(ephemeral_signing_key.to_bytes());
hasher.update(shared_point.as_bytes());
hasher.finalize().to_vec()
};
// Derive shared secret using ECDH
let shared_secret_bytes = ephemeral_signing_key.diffie_hellman(&recipient_key);
// Derive encryption key from the shared secret (using a simple hash for this example)
let mut hasher = Sha256::default();
hasher.update(shared_secret_bytes.as_bytes());
let encryption_key = hasher.finalize().to_vec();
// Encrypt the message using the derived key
let ciphertext = implementation::encrypt_with_key(&shared_secret, message)
let ciphertext = implementation::encrypt_with_key(&encryption_key, message)
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
// Format: ephemeral_public_key || ciphertext
@ -252,17 +250,16 @@ impl KeyPair {
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?;
// Derive shared secret (simplified ECDH)
let shared_point = sender_key.to_encoded_point(false);
let shared_secret = {
let mut hasher = Sha256::default();
hasher.update(self.signing_key.to_bytes());
hasher.update(shared_point.as_bytes());
hasher.finalize().to_vec()
};
// Derive shared secret using ECDH
let shared_secret_bytes = self.signing_key.diffie_hellman(&sender_key);
// Derive encryption key from the shared secret (using the same simple hash)
let mut hasher = Sha256::default();
hasher.update(shared_secret_bytes.as_bytes());
let encryption_key = hasher.finalize().to_vec();
// Decrypt the message using the derived key
implementation::decrypt_with_key(&shared_secret, actual_ciphertext)
implementation::decrypt_with_key(&encryption_key, actual_ciphertext)
.map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
}
}

View File

@ -13,3 +13,6 @@ pub use session_manager::{
keypair_pub_key, derive_public_key, keypair_sign, keypair_verify,
verify_with_public_key, encrypt_asymmetric, decrypt_asymmetric
};
#[cfg(test)]
mod tests;

View File

@ -0,0 +1,7 @@
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

View File

@ -0,0 +1,86 @@
use crate::vault::keypair::keypair_types::{KeyPair, KeySpace};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_keypair_creation() {
let keypair = KeyPair::new("test_keypair");
assert_eq!(keypair.name, "test_keypair");
// Basic check that keys are generated (they should have non-zero length)
assert!(!keypair.pub_key().is_empty());
}
#[test]
fn test_keypair_sign_and_verify() {
let keypair = KeyPair::new("test_keypair");
let message = b"This is a test message";
let signature = keypair.sign(message);
assert!(!signature.is_empty());
let is_valid = keypair.verify(message, &signature).expect("Verification failed");
assert!(is_valid);
// Test with a wrong message
let wrong_message = b"This is a different message";
let is_valid_wrong = keypair.verify(wrong_message, &signature).expect("Verification failed with wrong message");
assert!(!is_valid_wrong);
}
#[test]
fn test_verify_with_public_key() {
let keypair = KeyPair::new("test_keypair");
let message = b"Another test message";
let signature = keypair.sign(message);
let public_key = keypair.pub_key();
let is_valid = KeyPair::verify_with_public_key(&public_key, message, &signature).expect("Verification with public key failed");
assert!(is_valid);
// Test with a wrong public key
let wrong_keypair = KeyPair::new("wrong_keypair");
let wrong_public_key = wrong_keypair.pub_key();
let is_valid_wrong_key = KeyPair::verify_with_public_key(&wrong_public_key, message, &signature).expect("Verification with wrong public key failed");
assert!(!is_valid_wrong_key);
}
#[test]
fn test_asymmetric_encryption_decryption() {
// Sender's keypair
let sender_keypair = KeyPair::new("sender");
let sender_public_key = sender_keypair.pub_key();
// Recipient's keypair
let recipient_keypair = KeyPair::new("recipient");
let recipient_public_key = recipient_keypair.pub_key();
let message = b"This is a secret message";
// Sender encrypts for recipient
let ciphertext = sender_keypair.encrypt_asymmetric(&recipient_public_key, message).expect("Encryption failed");
assert!(!ciphertext.is_empty());
// Recipient decrypts
let decrypted_message = recipient_keypair.decrypt_asymmetric(&ciphertext).expect("Decryption failed");
assert_eq!(decrypted_message, message);
// Test decryption with wrong keypair
let wrong_keypair = KeyPair::new("wrong_recipient");
let result = wrong_keypair.decrypt_asymmetric(&ciphertext);
assert!(result.is_err());
}
#[test]
fn test_keyspace_add_keypair() {
let mut space = KeySpace::new("test_space");
space.add_keypair("keypair1").expect("Failed to add keypair1");
assert_eq!(space.keypairs.len(), 1);
assert!(space.keypairs.contains_key("keypair1"));
// Test adding a duplicate keypair
let result = space.add_keypair("keypair1");
assert!(result.is_err());
}
}

View File

@ -0,0 +1,3 @@
mod implementation_tests;
mod keypair_types_tests;
mod session_manager_tests;

View File

@ -0,0 +1,111 @@
use crate::vault::keypair::session_manager::{
clear_session, create_keypair, create_space, get_current_space, get_selected_keypair,
list_keypairs, select_keypair, set_current_space, SESSION,
};
use crate::vault::keypair::keypair_types::KeySpace;
// Helper function to clear the session before each test
fn setup_test() {
clear_session();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_and_get_space() {
setup_test();
create_space("test_space").expect("Failed to create space");
let space = get_current_space().expect("Failed to get current space");
assert_eq!(space.name, "test_space");
}
#[test]
fn test_set_current_space() {
setup_test();
let space = KeySpace::new("another_space");
set_current_space(space.clone()).expect("Failed to set current space");
let current_space = get_current_space().expect("Failed to get current space");
assert_eq!(current_space.name, "another_space");
}
#[test]
fn test_clear_session() {
setup_test();
create_space("test_space").expect("Failed to create space");
clear_session();
let result = get_current_space();
assert!(result.is_err());
}
#[test]
fn test_create_and_select_keypair() {
setup_test();
create_space("test_space").expect("Failed to create space");
create_keypair("test_keypair").expect("Failed to create keypair");
let keypair = get_selected_keypair().expect("Failed to get selected keypair");
assert_eq!(keypair.name, "test_keypair");
select_keypair("test_keypair").expect("Failed to select keypair");
let selected_keypair = get_selected_keypair().expect("Failed to get selected keypair after select");
assert_eq!(selected_keypair.name, "test_keypair");
}
#[test]
fn test_list_keypairs() {
setup_test();
create_space("test_space").expect("Failed to create space");
create_keypair("keypair1").expect("Failed to create keypair1");
create_keypair("keypair2").expect("Failed to create keypair2");
let keypairs = list_keypairs().expect("Failed to list keypairs");
assert_eq!(keypairs.len(), 2);
assert!(keypairs.contains(&"keypair1".to_string()));
assert!(keypairs.contains(&"keypair2".to_string()));
}
#[test]
fn test_create_keypair_no_active_space() {
setup_test();
let result = create_keypair("test_keypair");
assert!(result.is_err());
}
#[test]
fn test_select_keypair_no_active_space() {
setup_test();
let result = select_keypair("test_keypair");
assert!(result.is_err());
}
#[test]
fn test_select_nonexistent_keypair() {
setup_test();
create_space("test_space").expect("Failed to create space");
let result = select_keypair("nonexistent_keypair");
assert!(result.is_err());
}
#[test]
fn test_get_selected_keypair_no_active_space() {
setup_test();
let result = get_selected_keypair();
assert!(result.is_err());
}
#[test]
fn test_get_selected_keypair_no_keypair_selected() {
setup_test();
create_space("test_space").expect("Failed to create space");
let result = get_selected_keypair();
assert!(result.is_err());
}
#[test]
fn test_list_keypairs_no_active_space() {
setup_test();
let result = list_keypairs();
assert!(result.is_err());
}
}

View File

@ -165,3 +165,9 @@ let loaded_store = KvStore::load("my_store", "secure_password")?;
let api_key = loaded_store.get("api_key")?;
println!("API Key: {}", api_key.unwrap_or_default());
```
## to test
```bash
cargo test --lib vault::keypair
```

View File

@ -12,3 +12,6 @@ pub use store::{
create_store, open_store, delete_store,
list_stores, get_store_path
};
#[cfg(test)]
mod tests;

View File

@ -355,7 +355,7 @@ impl KvStore {
// Save to disk
self.save()?;
Ok(())
Ok(())
}
/// Gets the name of the store.

View File

@ -0,0 +1 @@
mod store_tests;

View File

@ -0,0 +1,105 @@
use crate::vault::kvs::store::{create_store, delete_store, open_store, KvStore};
use std::path::PathBuf;
// Helper function to generate a unique store name for each test
fn generate_test_store_name() -> String {
use rand::Rng;
let random_string: String = rand::thread_rng()
.sample_iter(&rand::distributions::Alphanumeric)
.take(10)
.map(char::from)
.collect();
format!("test_store_{}", random_string)
}
// Helper function to clean up test stores
fn cleanup_test_store(name: &str) {
let _ = delete_store(name);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_and_open_store() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
assert_eq!(store.name(), store_name);
assert!(!store.is_encrypted());
let opened_store = open_store(&store_name, None).expect("Failed to open store");
assert_eq!(opened_store.name(), store_name);
assert!(!opened_store.is_encrypted());
cleanup_test_store(&store_name);
}
#[test]
fn test_set_and_get_value() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
store.set("key1", &"value1").expect("Failed to set value");
let value: String = store.get("key1").expect("Failed to get value");
assert_eq!(value, "value1");
cleanup_test_store(&store_name);
}
#[test]
fn test_delete_value() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
store.set("key1", &"value1").expect("Failed to set value");
store.delete("key1").expect("Failed to delete value");
let result: Result<String, _> = store.get("key1");
assert!(result.is_err());
cleanup_test_store(&store_name);
}
#[test]
fn test_contains_key() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
store.set("key1", &"value1").expect("Failed to set value");
assert!(store.contains("key1").expect("Failed to check contains"));
assert!(!store.contains("key2").expect("Failed to check contains"));
cleanup_test_store(&store_name);
}
#[test]
fn test_list_keys() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
store.set("key1", &"value1").expect("Failed to set value");
store.set("key2", &"value2").expect("Failed to set value");
let keys = store.keys().expect("Failed to list keys");
assert_eq!(keys.len(), 2);
assert!(keys.contains(&"key1".to_string()));
assert!(keys.contains(&"key2".to_string()));
cleanup_test_store(&store_name);
}
#[test]
fn test_clear_store() {
let store_name = generate_test_store_name();
let store = create_store(&store_name, false, None).expect("Failed to create store");
store.set("key1", &"value1").expect("Failed to set value");
store.set("key2", &"value2").expect("Failed to set value");
store.clear().expect("Failed to clear store");
let keys = store.keys().expect("Failed to list keys after clear");
assert!(keys.is_empty());
cleanup_test_store(&store_name);
}
}