• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! Tests of functionality related to credentials, credential-views, and credential suppliers.
15 
16 extern crate alloc;
17 
18 use crate::credential::matched::{
19     EmptyMatchedCredential, KeySeedMatchedCredential, ReferencedMatchedCredential,
20 };
21 use crate::credential::v1::MicSectionVerificationMaterial;
22 use crate::credential::{
23     book::{
24         init_cache_from_source, CachedCredentialSource, PossiblyCachedDiscoveryCryptoMaterialKind,
25     },
26     source::{CredentialSource, SliceCredentialSource},
27     v0::{V0DiscoveryCredential, V0},
28     v1::{V1BroadcastCredential, V1DiscoveryCredential, V1DiscoveryCryptoMaterial, V1},
29     MatchableCredential,
30 };
31 use crate::extended::{V1IdentityToken, V1_IDENTITY_TOKEN_LEN};
32 use alloc::vec::Vec;
33 use crypto_provider::{ed25519, CryptoProvider};
34 use crypto_provider_default::CryptoProviderImpl;
35 
36 type Ed25519ProviderImpl = <CryptoProviderImpl as CryptoProvider>::Ed25519;
37 
get_zeroed_v0_discovery_credential() -> V0DiscoveryCredential38 fn get_zeroed_v0_discovery_credential() -> V0DiscoveryCredential {
39     V0DiscoveryCredential::new([0u8; 32], [0u8; 32])
40 }
41 
get_constant_packed_v1_discovery_credential(value: u8) -> V1DiscoveryCredential42 fn get_constant_packed_v1_discovery_credential(value: u8) -> V1DiscoveryCredential {
43     V1BroadcastCredential::new(
44         [value; 32],
45         V1IdentityToken::from([value; V1_IDENTITY_TOKEN_LEN]),
46         // NOTE: This winds up being unused in these test cases
47         ed25519::PrivateKey::generate::<Ed25519ProviderImpl>(),
48     )
49     .derive_discovery_credential::<CryptoProviderImpl>()
50 }
51 
52 #[test]
cached_credential_source_keeps_same_entries_as_original()53 fn cached_credential_source_keeps_same_entries_as_original() {
54     let creds: [MatchableCredential<V1, KeySeedMatchedCredential>; 5] =
55         [0u8, 1, 2, 3, 4].map(|x| {
56             let match_data = KeySeedMatchedCredential::from([x; 32]);
57             MatchableCredential {
58                 discovery_credential: get_constant_packed_v1_discovery_credential(x),
59                 match_data,
60             }
61         });
62     let supplier = SliceCredentialSource::new(&creds);
63     let cache = init_cache_from_source::<_, _, 3, CryptoProviderImpl>(&supplier);
64     let cached = CachedCredentialSource::new(supplier, cache);
65     let cached_view = &cached;
66     assert_eq!(cached_view.iter().count(), 5);
67     // Now we're going to check that the pairings between the match-data
68     // and the MIC hmac key wind up being the same between the original
69     // creds list and what's provided by the cached source.
70     let expected: Vec<_> = creds
71         .iter()
72         .map(|cred| {
73             (
74                 *cred
75                     .discovery_credential
76                     .mic_extended_salt_verification_material::<CryptoProviderImpl>()
77                     .mic_hmac_key()
78                     .as_bytes(),
79                 ReferencedMatchedCredential::from(&cred.match_data),
80             )
81         })
82         .collect();
83     let actual: Vec<_> = cached_view
84         .iter()
85         .map(|(crypto_material, match_data)| {
86             (
87                 *crypto_material
88                     .mic_extended_salt_verification_material::<CryptoProviderImpl>()
89                     .mic_hmac_key()
90                     .as_bytes(),
91                 match_data,
92             )
93         })
94         .collect();
95     assert_eq!(actual, expected);
96 }
97 
98 #[test]
cached_credential_source_has_requested_cache_size()99 fn cached_credential_source_has_requested_cache_size() {
100     let creds: [MatchableCredential<V0, EmptyMatchedCredential>; 10] =
101         [0u8; 10].map(|_| MatchableCredential {
102             discovery_credential: get_zeroed_v0_discovery_credential(),
103             match_data: EmptyMatchedCredential,
104         });
105     let supplier = SliceCredentialSource::new(&creds);
106     let cache = init_cache_from_source::<_, _, 5, CryptoProviderImpl>(&supplier);
107     let cached = CachedCredentialSource::new(supplier, cache);
108     let cached_view = &cached;
109     assert_eq!(cached_view.iter().count(), 10);
110     for (i, (cred, _)) in cached_view.iter().enumerate() {
111         if i < 5 {
112             // Should be cached
113             if let PossiblyCachedDiscoveryCryptoMaterialKind::Precalculated(_) = cred.wrapped {
114             } else {
115                 panic!("Credential #{} was not cached", i);
116             }
117         } else {
118             // Should be discovery credentials
119             if let PossiblyCachedDiscoveryCryptoMaterialKind::Discovery(_) = cred.wrapped {
120             } else {
121                 panic!("Credential #{} was not supposed to be cached", i);
122             }
123         }
124     }
125 }
126 
127 mod coverage_gaming {
128     use crate::credential::MetadataDecryptionError;
129     use alloc::format;
130 
131     #[test]
metadata_decryption_error_debug()132     fn metadata_decryption_error_debug() {
133         let err = MetadataDecryptionError;
134         let _ = format!("{:?}", err);
135     }
136 }
137