1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Credential types used in deserialization.
16 //!
17 //! While simple implementations are provided to get started with, there is likely opportunity for
18 //! efficiency gains with implementations tailored to suit (e.g. caching a few hot credentials
19 //! rather than reading from disk every time, etc).
20 
21 use crate::credential::matched::{MatchedCredential, ReferencedMatchedCredential};
22 use core::fmt::Debug;
23 use crypto_provider::{aead::Aead, aes, CryptoProvider, FromCryptoRng};
24 
25 pub mod book;
26 pub mod matched;
27 pub mod source;
28 pub mod v0;
29 pub mod v1;
30 
31 #[cfg(any(test, feature = "alloc"))]
32 pub mod metadata;
33 
34 #[cfg(test)]
35 mod tests;
36 
37 /// Information about a credential as supplied by the caller.
38 pub struct MatchableCredential<V: ProtocolVersion, M: MatchedCredential> {
39     /// The cryptographic information associated
40     /// with this particular credential which is used for discovering
41     /// advertisements/advertisement sections generated via the
42     /// paired sender credential.
43     pub discovery_credential: V::DiscoveryCredential,
44     /// The data which will be yielded back to the caller upon a successful
45     /// identity-match against this credential.
46     pub match_data: M,
47 }
48 
49 impl<V: ProtocolVersion, M: MatchedCredential> MatchableCredential<V, M> {
50     /// Views this credential as a (borrowed) discovery-credential
51     /// combined with some matched credential data
52     /// (which is copied - see documentation on [`MatchedCredential`])
as_pair(&self) -> (&V::DiscoveryCredential, ReferencedMatchedCredential<M>)53     pub fn as_pair(&self) -> (&V::DiscoveryCredential, ReferencedMatchedCredential<M>) {
54         (&self.discovery_credential, ReferencedMatchedCredential::from(&self.match_data))
55     }
56 }
57 
58 /// Error returned when metadata decryption fails.
59 #[derive(Debug, Eq, PartialEq)]
60 pub struct MetadataDecryptionError;
61 
62 /// Seal for protocol versions to enforce totality.
63 pub(crate) mod protocol_version_seal {
64     /// Internal-only supertrait of protocol versions
65     /// for the purpose of sealing the trait.
66     pub trait ProtocolVersionSeal: Clone {}
67 }
68 
69 /// Marker trait for protocol versions (V0/V1)
70 /// and associated data about them.
71 pub trait ProtocolVersion: protocol_version_seal::ProtocolVersionSeal {
72     /// The discovery credential type for this protocol version, which
73     /// is the minimal amount of cryptographic materials that we need
74     /// in order to discover advertisements/sections which make
75     /// use of the sender-paired version of the credential.
76     type DiscoveryCredential: DiscoveryMetadataCryptoMaterial<Self> + Clone;
77 
78     /// The native-length identity token for this protocol version
79     /// [i.e: if V0, a 14-byte identity token, or if V1, a 16-byte
80     /// identity token.]
81     type IdentityToken: Clone + AsRef<[u8]> + FromCryptoRng;
82 
83     /// Computes the metadata nonce for this version from the given key-seed.
metadata_nonce_from_key_seed<C: CryptoProvider>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, ) -> <C::Aes128Gcm as Aead>::Nonce84     fn metadata_nonce_from_key_seed<C: CryptoProvider>(
85         hkdf: &np_hkdf::NpKeySeedHkdf<C>,
86     ) -> <C::Aes128Gcm as Aead>::Nonce;
87 
88     // TODO this should be done by the identity provider that owns the corresponding credential
89     /// Transforms the passed metadata key (if needed) to a 16-byte metadata key
90     /// which may be used for metadata encryption/decryption
extract_metadata_key<C: CryptoProvider>( identity_token: Self::IdentityToken, ) -> aes::Aes128Key91     fn extract_metadata_key<C: CryptoProvider>(
92         identity_token: Self::IdentityToken,
93     ) -> aes::Aes128Key;
94 }
95 
96 /// Trait for structures which provide cryptographic
97 /// materials for discovery in a particular protocol version.
98 /// See [`crate::credential::v0::V0DiscoveryCryptoMaterial`]
99 /// and [`crate::credential::v1::V1DiscoveryCryptoMaterial`]
100 /// for V0 and V1 specializations.
101 pub trait DiscoveryMetadataCryptoMaterial<V: ProtocolVersion> {
102     /// Constructs or copies the metadata nonce used for decryption of associated credential
103     /// metadata for the identity represented via this crypto material.
metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12]104     fn metadata_nonce<C: CryptoProvider>(&self) -> [u8; 12];
105 }
106