Skip to content

Commit

Permalink
test(crypto): CRP-2231 split remote vault integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
altkdf committed Jan 30, 2024
1 parent 083e6b7 commit e1ebc89
Show file tree
Hide file tree
Showing 12 changed files with 826 additions and 786 deletions.
7 changes: 5 additions & 2 deletions rs/crypto/internal/crypto_service_provider/BUILD.bazel
@@ -1,4 +1,5 @@
load("@rules_rust//rust:defs.bzl", "rust_doc_test", "rust_library", "rust_test", "rust_test_suite")
load("@rules_rust//rust:defs.bzl", "rust_doc_test", "rust_library", "rust_test")
load("//bazel:defs.bzl", "rust_test_suite_with_extra_srcs")
load("//bazel:prost.bzl", "generated_files_check")

package(default_visibility = ["//rs/crypto:__subpackages__"])
Expand Down Expand Up @@ -121,14 +122,16 @@ rust_test(
deps = DEV_DEPENDENCIES,
)

rust_test_suite(
rust_test_suite_with_extra_srcs(
name = "crypto_service_provider_integration",
srcs = glob(
["tests/**/*.rs"],
exclude = [
"tests/check_generated_files.rs",
"tests/remote_csp_vault/common/*.rs",
],
),
extra_srcs = glob(["tests/remote_csp_vault/common/*.rs"]),
proc_macro_deps = MACRO_DEPENDENCIES + DEV_MACRO_DEPENDENCIES,
deps = [":crypto_service_provider"] + DEPENDENCIES + DEV_DEPENDENCIES,
)
Expand Down
784 changes: 0 additions & 784 deletions rs/crypto/internal/crypto_service_provider/tests/remote_csp_vault.rs

This file was deleted.

@@ -0,0 +1,95 @@
use assert_matches::assert_matches;
use ic_crypto_internal_basic_sig_ed25519 as ed25519;
use ic_crypto_internal_csp::key_id::KeyId;
use ic_crypto_internal_csp::types::{CspPublicKey, CspSignature};
use ic_crypto_internal_csp_proptest_utils::{
arb_algorithm_id, arb_csp_basic_signature_error, arb_csp_basic_signature_keygen_error,
arb_csp_public_key, arb_csp_signature, arb_key_id,
};
use ic_crypto_temp_crypto_vault::RemoteVaultEnvironment;
use ic_crypto_test_utils_local_csp_vault::MockLocalCspVault;
use ic_types::crypto::AlgorithmId;
use proptest::collection::vec;
use proptest::prelude::any;
use proptest::result::maybe_err;
use proptest::{prop_assert_eq, proptest};
use std::sync::Arc;

mod common;
use common::{local_vault_in_temp_dir, proptest_config_for_delegation};

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_sign(
algorithm_id in arb_algorithm_id(),
key_id in arb_key_id(),
message in vec(any::<u8>(), 0..1024),
expected_result in maybe_err(arb_csp_signature(), arb_csp_basic_signature_error())
) {
let expected_message = message.clone();
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_sign()
.times(1)
.withf(move |algorithm_id_, message_, key_id_| {
*algorithm_id_ == algorithm_id && message_ == &expected_message && *key_id_ == key_id
})
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.sign(algorithm_id, message, key_id);

prop_assert_eq!(result, expected_result);
}
}

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_gen_node_signing_key_pair(
expected_result in maybe_err(arb_csp_public_key(), arb_csp_basic_signature_keygen_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_gen_node_signing_key_pair()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.gen_node_signing_key_pair();

prop_assert_eq!(result, expected_result);
}
}

#[test]
fn should_sign_a_large_hundred_megabytes_message() {
const HUNDRED_MEGA_BYTES: usize = 100 * 1024 * 1024;
let message = vec![0_u8; HUNDRED_MEGA_BYTES];
let (vault, _temp_dir) = local_vault_in_temp_dir();
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(vault));
let remote_vault = env.new_vault_client();

let node_signing_public_key = remote_vault
.gen_node_signing_key_pair()
.expect("failed to generate keys");

let signature = remote_vault
.sign(
AlgorithmId::Ed25519,
message.clone(),
KeyId::try_from(&node_signing_public_key).unwrap(),
)
.expect("could not sign large message");

match (node_signing_public_key, signature) {
(CspPublicKey::Ed25519(public_key_bytes), CspSignature::Ed25519(signature_bytes)) => {
let verification = ed25519::verify(&signature_bytes, &message, &public_key_bytes);
assert_matches!(verification, Ok(()))
}
_ => panic!("unexpected type for node signing public key or signature"),
}
}
@@ -0,0 +1,35 @@
use ic_crypto_internal_csp::public_key_store::proto_pubkey_store::ProtoPublicKeyStore;
use ic_crypto_internal_csp::secret_key_store::proto_store::ProtoSecretKeyStore;
use ic_crypto_internal_csp::LocalCspVault;
use ic_crypto_internal_logmon::metrics::CryptoMetrics;
use ic_logger::replica_logger::no_op_logger;
use proptest::prelude::ProptestConfig;
use rand::rngs::OsRng;
use std::sync::Arc;
use tempfile::TempDir;

#[allow(unused)]
pub fn local_vault_in_temp_dir() -> (
LocalCspVault<OsRng, ProtoSecretKeyStore, ProtoSecretKeyStore, ProtoPublicKeyStore>,
TempDir,
) {
use ic_config::crypto::CryptoConfig;

let (config, _temp_dir) = CryptoConfig::new_in_temp_dir();
let local_vault = LocalCspVault::new_in_dir(
&config.crypto_root,
Arc::new(CryptoMetrics::none()),
no_op_logger(),
);
(local_vault, _temp_dir)
}

#[allow(unused)]
pub fn proptest_config_for_delegation() -> ProptestConfig {
ProptestConfig {
//default uses FileFailurePersistence::SourceParallel which expects a main.rs or a lib.rs,
//which does not work for a Rust integration test and results in a warning being printed.
failure_persistence: None,
..ProptestConfig::default()
}
}
@@ -0,0 +1,61 @@
use ic_crypto_internal_csp_proptest_utils::{
arb_algorithm_id, arb_csp_multi_signature_error, arb_csp_multi_signature_keygen_error,
arb_csp_pop, arb_csp_public_key, arb_csp_signature, arb_key_id,
};
use ic_crypto_temp_crypto_vault::RemoteVaultEnvironment;
use ic_crypto_test_utils_local_csp_vault::MockLocalCspVault;
use proptest::collection::vec;
use proptest::prelude::any;
use proptest::result::maybe_err;
use proptest::{prop_assert_eq, proptest};
use std::sync::Arc;

mod common;
use common::proptest_config_for_delegation;

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_multi_sign(
algorithm_id in arb_algorithm_id(),
key_id in arb_key_id(),
message in vec(any::<u8>(), 0..1024),
expected_result in maybe_err(arb_csp_signature(), arb_csp_multi_signature_error())
) {
let expected_message = message.clone();
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_multi_sign()
.times(1)
.withf(move |algorithm_id_, message_, key_id_| {
*algorithm_id_ == algorithm_id && message_ == &expected_message && *key_id_ == key_id
})
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.multi_sign(algorithm_id, message, key_id);

prop_assert_eq!(result, expected_result);
}
}

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_gen_committee_signing_key_pair(
expected_result in maybe_err((arb_csp_public_key(), arb_csp_pop()), arb_csp_multi_signature_keygen_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_gen_committee_signing_key_pair()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.gen_committee_signing_key_pair();

prop_assert_eq!(result, expected_result);
}
}
@@ -0,0 +1,86 @@
use ic_crypto_temp_crypto_vault::RemoteVaultEnvironment;
use ic_crypto_test_utils_local_csp_vault::MockLocalCspVault;
use proptest::prelude::any;
use proptest::result::maybe_err;
use proptest::{prop_assert_eq, proptest};
use std::sync::Arc;

mod common;
use common::proptest_config_for_delegation;

use ic_crypto_internal_csp_proptest_utils::{
arb_external_public_keys, arb_pks_and_sks_contains_errors, arb_validate_pks_and_sks_error,
};
use ic_crypto_node_key_validation::{ValidNodePublicKeys, ValidNodeSigningPublicKey};
use ic_crypto_test_utils_keys::public_keys::{
valid_committee_signing_public_key, valid_dkg_dealing_encryption_public_key,
valid_idkg_dealing_encryption_public_key, valid_node_signing_public_key,
valid_tls_certificate_and_validation_time,
};
use ic_types::crypto::CurrentNodePublicKeys;
use proptest::prelude::Just;
use proptest::result::maybe_err_weighted;

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_pks_and_sks_contains(
external_public_keys in arb_external_public_keys(),
expected_result in maybe_err(any::<()>(), arb_pks_and_sks_contains_errors())
) {
let mut local_vault = MockLocalCspVault::new();
let expected_external_public_keys = external_public_keys.clone();
local_vault
.expect_pks_and_sks_contains()
.times(1)
.withf(move |external_public_keys_| {
*external_public_keys_ == expected_external_public_keys
})
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.pks_and_sks_contains(external_public_keys);

prop_assert_eq!(result, expected_result);
}
}

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_validate_pks_and_sks(
expected_result in maybe_err_weighted(0.95, Just(valid_node_public_keys()), arb_validate_pks_and_sks_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_validate_pks_and_sks()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.validate_pks_and_sks();

prop_assert_eq!(result, expected_result);
}
}

fn valid_node_public_keys() -> ValidNodePublicKeys {
let node_id = *ValidNodeSigningPublicKey::try_from(valid_node_signing_public_key())
.expect("invalid node signing public key")
.derived_node_id();
let (valid_tls_certificate, validation_time) = valid_tls_certificate_and_validation_time();
ValidNodePublicKeys::try_from(
CurrentNodePublicKeys {
node_signing_public_key: Some(valid_node_signing_public_key()),
committee_signing_public_key: Some(valid_committee_signing_public_key()),
tls_certificate: Some(valid_tls_certificate),
dkg_dealing_encryption_public_key: Some(valid_dkg_dealing_encryption_public_key()),
idkg_dealing_encryption_public_key: Some(valid_idkg_dealing_encryption_public_key()),
},
node_id,
validation_time,
)
.expect("invalid node public keys")
}
@@ -0,0 +1,72 @@
use ic_crypto_internal_csp_proptest_utils::{
arb_csp_public_key_store_error, arb_current_node_public_keys,
};
use ic_crypto_temp_crypto_vault::RemoteVaultEnvironment;
use ic_crypto_test_utils_local_csp_vault::MockLocalCspVault;
use proptest::prelude::any;
use proptest::result::maybe_err;
use proptest::{prop_assert_eq, proptest};
use std::sync::Arc;

mod common;
use common::proptest_config_for_delegation;

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_current_node_public_keys(
expected_result in maybe_err(arb_current_node_public_keys(), arb_csp_public_key_store_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_current_node_public_keys()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.current_node_public_keys();

prop_assert_eq!(result, expected_result);
}
}

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_current_node_public_keys_with_timestamps(
expected_result in maybe_err(arb_current_node_public_keys(), arb_csp_public_key_store_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_current_node_public_keys_with_timestamps()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.current_node_public_keys_with_timestamps();

prop_assert_eq!(result, expected_result);
}
}

proptest! {
#![proptest_config(proptest_config_for_delegation())]
#[test]
fn should_delegate_for_idkg_dealing_encryption_pubkeys_count(
expected_result in maybe_err(any::<usize>(), arb_csp_public_key_store_error())
) {
let mut local_vault = MockLocalCspVault::new();
local_vault
.expect_idkg_dealing_encryption_pubkeys_count()
.times(1)
.return_const(expected_result.clone());
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
let remote_vault = env.new_vault_client();

let result = remote_vault.idkg_dealing_encryption_pubkeys_count();

prop_assert_eq!(result, expected_result);
}
}

0 comments on commit e1ebc89

Please sign in to comment.