#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
use crate::security::cryptographic::CryptoTransformKeyId;
use super::{
aes_gcm_gmac::validate_mac,
key_material::ReceiverSpecificKeyMaterial,
types::{BuiltinInitializationVector, BuiltinMAC, ReceiverSpecificMAC},
DecodeSessionMaterials,
};
fn find_receiver_specific_mac<'a>(
receiver_specific_key_id: &CryptoTransformKeyId,
receiver_specific_macs: &'a [ReceiverSpecificMAC],
) -> Option<&'a BuiltinMAC> {
receiver_specific_macs
.iter()
.find(
|ReceiverSpecificMAC {
receiver_mac_key_id,
..
}| receiver_mac_key_id.eq(receiver_specific_key_id),
)
.map(|ReceiverSpecificMAC { receiver_mac, .. }| receiver_mac)
}
pub(super) fn validate_receiver_specific_mac(
decode_materials: &DecodeSessionMaterials,
initialization_vector: &BuiltinInitializationVector,
common_mac: &BuiltinMAC,
receiver_specific_macs: &[ReceiverSpecificMAC],
) -> bool {
if let DecodeSessionMaterials {
receiver_specific_key: Some(ReceiverSpecificKeyMaterial { key_id, key }),
..
} = decode_materials
{
if let Some(receiver_specific_mac) = find_receiver_specific_mac(key_id, receiver_specific_macs)
{
validate_mac(
key,
*initialization_vector,
common_mac,
*receiver_specific_mac,
)
.map_or_else(
|e| {
error!("Decoding receiver-specific MAC failed: {e}");
false
},
|_| true, )
} else {
trace!(
"No receiver-specific MAC found for the receiver-specific key id {key_id:?}, rejecting."
);
false
}
} else {
true
}
}