1 // Copyright 2024 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 #![allow(clippy::unwrap_used)]
16
17 use super::*;
18 use crate::extended::V1_IDENTITY_TOKEN_LEN;
19 use np_hkdf::v1_salt::{ExtendedV1Salt, EXTENDED_SALT_LEN};
20
21 #[cfg(test)]
22 mod mic_decrypt_tests;
23
24 #[cfg(test)]
25 mod signature_decrypt_tests;
26
27 #[cfg(test)]
28 mod coverage_gaming;
29
30 /// An error when attempting to resolve an identity and then
31 /// attempt to deserialize an encrypted advertisement.
32 ///
33 /// This should not be exposed publicly, since it's too
34 /// detailed.
35 #[derive(Debug, PartialEq, Eq)]
36 pub(crate) enum IdentityResolutionOrDeserializationError<V: VerificationError> {
37 /// Failed to match the encrypted adv to an identity
38 IdentityMatchingError,
39 /// Failed to deserialize the encrypted adv after matching the identity
40 DeserializationError(DeserializationError<V>),
41 }
42
43 impl<V: VerificationError> From<DeserializationError<V>>
44 for IdentityResolutionOrDeserializationError<V>
45 {
from(deserialization_error: DeserializationError<V>) -> Self46 fn from(deserialization_error: DeserializationError<V>) -> Self {
47 Self::DeserializationError(deserialization_error)
48 }
49 }
50
51 impl<V: VerificationError> From<V> for IdentityResolutionOrDeserializationError<V> {
from(verification_error: V) -> Self52 fn from(verification_error: V) -> Self {
53 Self::DeserializationError(DeserializationError::VerificationError(verification_error))
54 }
55 }
56
first_section_contents(after_version_header: &[u8]) -> &[u8]57 pub(crate) fn first_section_contents(after_version_header: &[u8]) -> &[u8] {
58 &after_version_header[1 + EXTENDED_SALT_LEN + V1_IDENTITY_TOKEN_LEN + 1..]
59 }
60
first_section_identity_token( salt: MultiSalt, after_version_header: &[u8], ) -> CiphertextExtendedIdentityToken61 pub(crate) fn first_section_identity_token(
62 salt: MultiSalt,
63 after_version_header: &[u8],
64 ) -> CiphertextExtendedIdentityToken {
65 // Next 16 bytes after 1 byte format and 16 byte salt
66 after_version_header[1 + salt.as_slice().len()..][..V1_IDENTITY_TOKEN_LEN]
67 .try_into()
68 .map(|arr: [u8; V1_IDENTITY_TOKEN_LEN]| arr.into())
69 .unwrap()
70 }
71
first_section_format(after_version_header: &[u8]) -> &[u8]72 pub(crate) fn first_section_format(after_version_header: &[u8]) -> &[u8] {
73 // 1 byte of format comes at the beginning
74 &after_version_header[..1]
75 }
76
first_section_salt(after_version_header: &[u8]) -> ExtendedV1Salt77 pub(crate) fn first_section_salt(after_version_header: &[u8]) -> ExtendedV1Salt {
78 // Next 16 bytes after 1 byte format
79 after_version_header[1..][..EXTENDED_SALT_LEN]
80 .try_into()
81 .map(|arr: [u8; EXTENDED_SALT_LEN]| arr.into())
82 .unwrap()
83 }
84
first_section_contents_len(after_version_header: &[u8]) -> u885 pub(crate) fn first_section_contents_len(after_version_header: &[u8]) -> u8 {
86 // section len is the first byte after format + salt + identity token
87 after_version_header[1 + EXTENDED_SALT_LEN + V1_IDENTITY_TOKEN_LEN..][0]
88 }
89