Skip to content

Commit 467b9f2

Browse files
committed
Merge branch 'gdemay/CRP-1929-SecretKeyStoreCspVault' into 'master'
test(crypto): CRP-1929 delegation proptest for `SecretKeyStoreCspVault` Ensures by a `proptest` that the remote CSP vault delegates to the local CSP vault when called on any method of the trait `SecretKeyStoreCspVault`. See merge request dfinity-lab/public/ic!12569
2 parents 3e2c66c + 808f385 commit 467b9f2

File tree

6 files changed

+126
-129
lines changed

6 files changed

+126
-129
lines changed

rs/crypto/internal/crypto_service_provider/csp_proptest_utils/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub use csp_multi_signature_error::arb_csp_multi_signature_error;
1717
pub use csp_multi_signature_keygen_error::arb_csp_multi_signature_keygen_error;
1818
pub use csp_pop::arb_csp_pop;
1919
pub use csp_public_key::arb_csp_public_key;
20+
pub use csp_secret_key_store_contains_error::arb_csp_secret_key_store_contains_error;
2021
pub use csp_signature::arb_csp_signature;
2122
pub use csp_threshold_sign_error::arb_csp_threshold_sign_error;
2223

@@ -272,3 +273,12 @@ mod csp_threshold_sign_error {
272273
InternalError => {internal_error in ".*"}
273274
);
274275
}
276+
277+
mod csp_secret_key_store_contains_error {
278+
use super::*;
279+
use ic_crypto_internal_csp::vault::api::CspSecretKeyStoreContainsError;
280+
281+
proptest_strategy_for_enum!(CspSecretKeyStoreContainsError;
282+
InternalError => {internal_error in ".*"}
283+
);
284+
}

rs/crypto/internal/crypto_service_provider/csp_proptest_utils/src/tests.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,12 @@ should_have_a_strategy_for_each_variant!(
142142
MalformedSecretKey { .. },
143143
InternalError { .. }
144144
);
145+
146+
use ic_crypto_internal_csp::vault::api::CspSecretKeyStoreContainsError;
147+
should_have_a_strategy_for_each_variant!(
148+
CspSecretKeyStoreContainsError,
149+
CspSecretKeyStoreContainsError::InternalError {
150+
internal_error: "dummy error to match upon".to_string(),
151+
},
152+
InternalError { .. }
153+
);
Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,89 @@
1+
#![allow(clippy::unwrap_used)]
12
//! Verifies the implementation of SecretKeyStoreCspVault for LocalCspVault.
2-
use crate::vault::test_utils;
3+
use crate::vault::api::BasicSignatureCspVault;
4+
use crate::vault::api::SecretKeyStoreCspVault;
5+
use crate::vault::api::TlsHandshakeCspVault;
6+
use crate::KeyId;
37
use crate::LocalCspVault;
8+
use ic_types_test_utils::ids::node_test_id;
9+
10+
const NODE_1: u64 = 4241;
11+
const NOT_AFTER: &str = "99991231235959Z";
412

513
#[test]
614
fn key_should_be_present_only_after_generation() {
7-
test_utils::sks::sks_should_contain_keys_only_after_generation(
8-
LocalCspVault::builder_for_test().build_into_arc(),
9-
LocalCspVault::builder_for_test().build_into_arc(),
15+
let csp_vault1 = LocalCspVault::builder_for_test().build_into_arc();
16+
let csp_vault2 = LocalCspVault::builder_for_test().build_into_arc();
17+
let public_key1 = csp_vault1
18+
.gen_node_signing_key_pair()
19+
.expect("Test setup failed: Failed to generate keys");
20+
let key_id1 = KeyId::try_from(&public_key1).unwrap();
21+
assert!(
22+
csp_vault1.sks_contains(&key_id1).expect("SKS call failed"),
23+
"Key should be present after generation."
24+
);
25+
assert!(
26+
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
27+
"Key should be absent if not generated in the CSP."
28+
);
29+
30+
let public_key2 = csp_vault2
31+
.gen_node_signing_key_pair()
32+
.expect("Test setup failed: Failed to generate keys");
33+
let key_id2 = KeyId::try_from(&public_key2).unwrap();
34+
assert_ne!(
35+
key_id1, key_id2,
36+
"Test failure: Key IDs from different CSPs were the same. Check random number generation."
37+
);
38+
assert!(
39+
csp_vault2.sks_contains(&key_id2).expect("SKS call failed"),
40+
"Key should be present in the CSP that generated it."
41+
);
42+
assert!(
43+
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
44+
"The second CSP should not contain the keys of the first."
45+
);
46+
assert!(
47+
!csp_vault1.sks_contains(&key_id2).expect("SKS call failed"),
48+
"Key first CSP should not contain the keys of the second."
1049
);
1150
}
1251

1352
#[test]
1453
fn tls_key_should_be_present_only_after_generation() {
15-
test_utils::sks::sks_should_contain_tls_keys_only_after_generation(
16-
LocalCspVault::builder_for_test().build_into_arc(),
17-
LocalCspVault::builder_for_test().build_into_arc(),
54+
let csp_vault1 = LocalCspVault::builder_for_test().build_into_arc();
55+
let csp_vault2 = LocalCspVault::builder_for_test().build_into_arc();
56+
let public_key_cert1 = csp_vault1
57+
.gen_tls_key_pair(node_test_id(NODE_1), NOT_AFTER)
58+
.expect("error generating TLS key pair");
59+
let key_id1 = KeyId::try_from(&public_key_cert1).unwrap();
60+
assert!(
61+
csp_vault1.sks_contains(&key_id1).expect("SKS call failed"),
62+
"TLS key should be present after generation."
63+
);
64+
assert!(
65+
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
66+
"TLS key should be absent if not generated in the CSP."
67+
);
68+
69+
let public_key_cert2 = csp_vault2
70+
.gen_tls_key_pair(node_test_id(NODE_1), NOT_AFTER)
71+
.expect("error generating TLS key pair");
72+
let key_id2 = KeyId::try_from(&public_key_cert2).unwrap();
73+
assert_ne!(
74+
key_id1, key_id2,
75+
"Test failure: Key IDs from different CSPs were the same. Check random number generation."
76+
);
77+
assert!(
78+
csp_vault2.sks_contains(&key_id2).expect("SKS call failed"),
79+
"TLS key should be present in the CSP that generated it."
80+
);
81+
assert!(
82+
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
83+
"The second CSP should not contain the TLS keys of the first."
84+
);
85+
assert!(
86+
!csp_vault1.sks_contains(&key_id2).expect("SKS call failed"),
87+
"Key first CSP should not contain the TLS keys of the second."
1888
);
1989
}

rs/crypto/internal/crypto_service_provider/src/vault/remote_csp_vault/tests.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,34 +90,6 @@ mod timeout {
9090
}
9191
}
9292

93-
mod secret_key_store {
94-
use super::*;
95-
96-
#[test]
97-
fn key_should_be_present_only_after_generation() {
98-
let tokio_rt = new_tokio_runtime();
99-
let (vault_1, vault_2) = new_csp_vaults_for_test(tokio_rt.handle());
100-
101-
test_utils::sks::sks_should_contain_keys_only_after_generation(vault_1, vault_2);
102-
}
103-
104-
#[test]
105-
fn tls_key_should_be_present_only_after_generation() {
106-
let tokio_rt = new_tokio_runtime();
107-
let (vault_1, vault_2) = new_csp_vaults_for_test(tokio_rt.handle());
108-
109-
test_utils::sks::sks_should_contain_tls_keys_only_after_generation(vault_1, vault_2);
110-
}
111-
112-
fn new_csp_vaults_for_test(
113-
rt_handle: &tokio::runtime::Handle,
114-
) -> (Arc<dyn CspVault>, Arc<dyn CspVault>) {
115-
let csp_vault_1 = new_remote_csp_vault(rt_handle);
116-
let csp_vault_2 = new_remote_csp_vault(rt_handle);
117-
(csp_vault_1, csp_vault_2)
118-
}
119-
}
120-
12193
mod ni_dkg {
12294
use super::*;
12395
use crate::public_key_store::mock_pubkey_store::MockPublicKeyStore;

rs/crypto/internal/crypto_service_provider/src/vault/test_utils/sks.rs

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,10 @@
1-
#![allow(clippy::unwrap_used)]
21
use crate::secret_key_store::mock_secret_key_store::MockSecretKeyStore;
32
use crate::secret_key_store::temp_secret_key_store::TempSecretKeyStore;
43
use crate::secret_key_store::SecretKeyStoreInsertionError;
54
use crate::types::CspSecretKey;
6-
use crate::vault::api::CspVault;
75
use crate::{KeyId, SecretKeyStore};
86
use ic_crypto_internal_tls::keygen::TlsEd25519SecretKeyDerBytes;
9-
use ic_types_test_utils::ids::node_test_id;
107
use openssl::pkey::PKey;
11-
use std::sync::Arc;
12-
13-
const NODE_1: u64 = 4241;
14-
const NOT_AFTER: &str = "99991231235959Z";
15-
16-
/// Key should be present only after key generation.
17-
///
18-
/// Note: Theoretically the invariant is: The key should be present only in the
19-
/// CSP that generated it, and only after generation and before deletion, if
20-
/// deletion is supported for that key type. Thus ideally there should be a
21-
/// test that generates many sequences of events and verifies that this
22-
/// invariant holds, regardless of the sequence of events, the number or type of
23-
/// keys in the CSP and so on. Making such a test is hard, so this is just one
24-
/// sequence of events.
25-
pub fn sks_should_contain_keys_only_after_generation(
26-
csp_vault1: Arc<dyn CspVault>,
27-
csp_vault2: Arc<dyn CspVault>,
28-
) {
29-
let public_key1 = csp_vault1
30-
.gen_node_signing_key_pair()
31-
.expect("Test setup failed: Failed to generate keys");
32-
let key_id1 = KeyId::try_from(&public_key1).unwrap();
33-
assert!(
34-
csp_vault1.sks_contains(&key_id1).expect("SKS call failed"),
35-
"Key should be present after generation."
36-
);
37-
assert!(
38-
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
39-
"Key should be absent if not generated in the CSP."
40-
);
41-
42-
let public_key2 = csp_vault2
43-
.gen_node_signing_key_pair()
44-
.expect("Test setup failed: Failed to generate keys");
45-
let key_id2 = KeyId::try_from(&public_key2).unwrap();
46-
assert_ne!(
47-
key_id1, key_id2,
48-
"Test failure: Key IDs from different CSPs were the same. Check random number generation."
49-
);
50-
assert!(
51-
csp_vault2.sks_contains(&key_id2).expect("SKS call failed"),
52-
"Key should be present in the CSP that generated it."
53-
);
54-
assert!(
55-
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
56-
"The second CSP should not contain the keys of the first."
57-
);
58-
assert!(
59-
!csp_vault1.sks_contains(&key_id2).expect("SKS call failed"),
60-
"Key first CSP should not contain the keys of the second."
61-
);
62-
}
63-
64-
pub fn sks_should_contain_tls_keys_only_after_generation(
65-
csp_vault1: Arc<dyn CspVault>,
66-
csp_vault2: Arc<dyn CspVault>,
67-
) {
68-
let public_key_cert1 = csp_vault1
69-
.gen_tls_key_pair(node_test_id(NODE_1), NOT_AFTER)
70-
.expect("error generating TLS key pair");
71-
let key_id1 = KeyId::try_from(&public_key_cert1).unwrap();
72-
assert!(
73-
csp_vault1.sks_contains(&key_id1).expect("SKS call failed"),
74-
"TLS key should be present after generation."
75-
);
76-
assert!(
77-
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
78-
"TLS key should be absent if not generated in the CSP."
79-
);
80-
81-
let public_key_cert2 = csp_vault2
82-
.gen_tls_key_pair(node_test_id(NODE_1), NOT_AFTER)
83-
.expect("error generating TLS key pair");
84-
let key_id2 = KeyId::try_from(&public_key_cert2).unwrap();
85-
assert_ne!(
86-
key_id1, key_id2,
87-
"Test failure: Key IDs from different CSPs were the same. Check random number generation."
88-
);
89-
assert!(
90-
csp_vault2.sks_contains(&key_id2).expect("SKS call failed"),
91-
"TLS key should be present in the CSP that generated it."
92-
);
93-
assert!(
94-
!csp_vault2.sks_contains(&key_id1).expect("SKS call failed"),
95-
"The second CSP should not contain the TLS keys of the first."
96-
);
97-
assert!(
98-
!csp_vault1.sks_contains(&key_id2).expect("SKS call failed"),
99-
"Key first CSP should not contain the TLS keys of the second."
100-
);
101-
}
1028

1039
pub fn secret_key_store_with_duplicated_key_id_error_on_insert(
10410
duplicated_key_id: KeyId,

rs/crypto/internal/crypto_service_provider/tests/remote_csp_vault.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,36 @@ mod threshold_signature_csp_vault {
461461
}
462462
}
463463

464+
mod secret_key_store_csp_vault {
465+
use super::*;
466+
use ic_crypto_internal_csp_proptest_utils::arb_csp_secret_key_store_contains_error;
467+
use ic_crypto_internal_csp_proptest_utils::arb_key_id;
468+
469+
proptest! {
470+
#![proptest_config(proptest_config_for_delegation())]
471+
#[test]
472+
fn should_delegate_for_sks_contains(
473+
key_id in arb_key_id(),
474+
expected_result in maybe_err(any::<bool>(), arb_csp_secret_key_store_contains_error())
475+
) {
476+
let mut local_vault = MockLocalCspVault::new();
477+
local_vault
478+
.expect_sks_contains()
479+
.times(1)
480+
.withf(move |key_id_| {
481+
*key_id_ == key_id
482+
})
483+
.return_const(expected_result.clone());
484+
let env = RemoteVaultEnvironment::start_server_with_local_csp_vault(Arc::new(local_vault));
485+
let remote_vault = env.new_vault_client();
486+
487+
let result = remote_vault.sks_contains(&key_id);
488+
489+
prop_assert_eq!(result, expected_result);
490+
}
491+
}
492+
}
493+
464494
fn local_vault_in_temp_dir() -> (
465495
LocalCspVault<OsRng, ProtoSecretKeyStore, ProtoSecretKeyStore, ProtoPublicKeyStore>,
466496
TempDir,

0 commit comments

Comments
 (0)