tests & fixes in kvs & keypair
This commit is contained in:
parent
3a0900fc15
commit
3f8aecb786
@ -21,7 +21,7 @@ env_logger = "0.10.0" # Logger implementation
|
|||||||
ethers = { version = "2.0.7", features = ["legacy"] } # Ethereum library
|
ethers = { version = "2.0.7", features = ["legacy"] } # Ethereum library
|
||||||
glob = "0.3.1" # For file pattern matching
|
glob = "0.3.1" # For file pattern matching
|
||||||
jsonrpsee = "0.25.1"
|
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
|
lazy_static = "1.4.0" # For lazy initialization of static variables
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4" # Logging facade
|
log = "0.4" # Logging facade
|
||||||
|
@ -214,18 +214,16 @@ impl KeyPair {
|
|||||||
let ephemeral_signing_key = SigningKey::random(&mut OsRng);
|
let ephemeral_signing_key = SigningKey::random(&mut OsRng);
|
||||||
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
|
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
|
||||||
|
|
||||||
// Derive shared secret (this is a simplified ECDH)
|
// Derive shared secret using ECDH
|
||||||
// In a real implementation, we would use proper ECDH, but for this example:
|
let shared_secret_bytes = ephemeral_signing_key.diffie_hellman(&recipient_key);
|
||||||
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 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
|
// 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()))?;
|
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
|
||||||
|
|
||||||
// Format: ephemeral_public_key || ciphertext
|
// Format: ephemeral_public_key || ciphertext
|
||||||
@ -252,17 +250,16 @@ impl KeyPair {
|
|||||||
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key)
|
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key)
|
||||||
.map_err(|_| CryptoError::InvalidKeyLength)?;
|
.map_err(|_| CryptoError::InvalidKeyLength)?;
|
||||||
|
|
||||||
// Derive shared secret (simplified ECDH)
|
// Derive shared secret using ECDH
|
||||||
let shared_point = sender_key.to_encoded_point(false);
|
let shared_secret_bytes = self.signing_key.diffie_hellman(&sender_key);
|
||||||
let shared_secret = {
|
|
||||||
let mut hasher = Sha256::default();
|
// Derive encryption key from the shared secret (using the same simple hash)
|
||||||
hasher.update(self.signing_key.to_bytes());
|
let mut hasher = Sha256::default();
|
||||||
hasher.update(shared_point.as_bytes());
|
hasher.update(shared_secret_bytes.as_bytes());
|
||||||
hasher.finalize().to_vec()
|
let encryption_key = hasher.finalize().to_vec();
|
||||||
};
|
|
||||||
|
|
||||||
// Decrypt the message using the derived key
|
// 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()))
|
.map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,3 +13,6 @@ pub use session_manager::{
|
|||||||
keypair_pub_key, derive_public_key, keypair_sign, keypair_verify,
|
keypair_pub_key, derive_public_key, keypair_sign, keypair_verify,
|
||||||
verify_with_public_key, encrypt_asymmetric, decrypt_asymmetric
|
verify_with_public_key, encrypt_asymmetric, decrypt_asymmetric
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
7
src/vault/keypair/tests/implementation_tests.rs
Normal file
7
src/vault/keypair/tests/implementation_tests.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
86
src/vault/keypair/tests/keypair_types_tests.rs
Normal file
86
src/vault/keypair/tests/keypair_types_tests.rs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
3
src/vault/keypair/tests/mod.rs
Normal file
3
src/vault/keypair/tests/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod implementation_tests;
|
||||||
|
mod keypair_types_tests;
|
||||||
|
mod session_manager_tests;
|
111
src/vault/keypair/tests/session_manager_tests.rs
Normal file
111
src/vault/keypair/tests/session_manager_tests.rs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
@ -165,3 +165,9 @@ let loaded_store = KvStore::load("my_store", "secure_password")?;
|
|||||||
let api_key = loaded_store.get("api_key")?;
|
let api_key = loaded_store.get("api_key")?;
|
||||||
println!("API Key: {}", api_key.unwrap_or_default());
|
println!("API Key: {}", api_key.unwrap_or_default());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## to test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test --lib vault::keypair
|
||||||
|
```
|
@ -12,3 +12,6 @@ pub use store::{
|
|||||||
create_store, open_store, delete_store,
|
create_store, open_store, delete_store,
|
||||||
list_stores, get_store_path
|
list_stores, get_store_path
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
@ -355,7 +355,7 @@ impl KvStore {
|
|||||||
// Save to disk
|
// Save to disk
|
||||||
self.save()?;
|
self.save()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the name of the store.
|
/// Gets the name of the store.
|
||||||
|
1
src/vault/kvs/tests/mod.rs
Normal file
1
src/vault/kvs/tests/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
mod store_tests;
|
105
src/vault/kvs/tests/store_tests.rs
Normal file
105
src/vault/kvs/tests/store_tests.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user