Skip to content

Commit abe4b49

Browse files
committed
tink-core: allow AAD for encrypted keyset storage
Merge upstream commit: - 84edb9ebea59 Adding an method to Read and Write KeysetHandle with associated data. Here: Golang
1 parent 072ebcb commit abe4b49

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

core/src/keyset/handle.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,24 @@ impl Handle {
5555
/// Attempt to create a [`Handle`] from an encrypted keyset obtained via a
5656
/// [`Reader`](crate::keyset::Reader).
5757
pub fn read<T>(reader: &mut T, master_key: Box<dyn crate::Aead>) -> Result<Self, TinkError>
58+
where
59+
T: crate::keyset::Reader,
60+
{
61+
Self::read_with_associated_data(reader, master_key, &[])
62+
}
63+
64+
/// Attempt to create a [`Handle`] from an encrypted keyset obtained via a
65+
/// [`Reader`](crate::keyset::Reader) using the provided associated data.
66+
pub fn read_with_associated_data<T>(
67+
reader: &mut T,
68+
master_key: Box<dyn crate::Aead>,
69+
associated_data: &[u8],
70+
) -> Result<Self, TinkError>
5871
where
5972
T: crate::keyset::Reader,
6073
{
6174
let encrypted_keyset = reader.read_encrypted()?;
62-
let ks = decrypt(&encrypted_keyset, master_key)?;
75+
let ks = decrypt(&encrypted_keyset, master_key, associated_data)?;
6376
Ok(Handle {
6477
ks: validate_keyset(ks)?,
6578
})
@@ -109,7 +122,20 @@ impl Handle {
109122
where
110123
T: super::Writer,
111124
{
112-
let encrypted = encrypt(&self.ks, master_key)?;
125+
self.write_with_associated_data(writer, master_key, &[])
126+
}
127+
128+
/// Encrypts and writes the enclosed [`Keyset`] using the provided associated data.
129+
pub fn write_with_associated_data<T>(
130+
&self,
131+
writer: &mut T,
132+
master_key: Box<dyn crate::Aead>,
133+
associated_data: &[u8],
134+
) -> Result<(), TinkError>
135+
where
136+
T: super::Writer,
137+
{
138+
let encrypted = encrypt(&self.ks, master_key, associated_data)?;
113139
writer.write_encrypted(&encrypted)
114140
}
115141

@@ -271,9 +297,10 @@ fn public_key_data(priv_key_data: &tink_proto::KeyData) -> Result<tink_proto::Ke
271297
fn decrypt(
272298
encrypted_keyset: &tink_proto::EncryptedKeyset,
273299
master_key: Box<dyn crate::Aead>,
300+
associated_data: &[u8],
274301
) -> Result<Keyset, TinkError> {
275302
let decrypted = master_key
276-
.decrypt(&encrypted_keyset.encrypted_keyset, &[])
303+
.decrypt(&encrypted_keyset.encrypted_keyset, associated_data)
277304
.map_err(|e| wrap_err("keyset::Handle: decryption failed", e))?;
278305
Keyset::decode(&decrypted[..]).map_err(|_| TinkError::new("keyset::Handle:: invalid keyset"))
279306
}
@@ -282,13 +309,14 @@ fn decrypt(
282309
fn encrypt(
283310
keyset: &Keyset,
284311
master_key: Box<dyn crate::Aead>,
312+
associated_data: &[u8],
285313
) -> Result<tink_proto::EncryptedKeyset, TinkError> {
286314
let mut serialized_keyset = vec![];
287315
keyset
288316
.encode(&mut serialized_keyset)
289317
.map_err(|e| wrap_err("keyset::Handle: invalid keyset", e))?;
290318
let encrypted = master_key
291-
.encrypt(&serialized_keyset, &[])
319+
.encrypt(&serialized_keyset, associated_data)
292320
.map_err(|e| wrap_err("keyset::Handle: encrypted failed", e))?;
293321
Ok(tink_proto::EncryptedKeyset {
294322
encrypted_keyset: encrypted,

tests/tests/core/keyset/handle_test.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,57 @@ fn test_read() {
8888
);
8989
}
9090

91+
#[test]
92+
fn test_read_with_associated_data() {
93+
let main_key = Box::new(tink_aead::subtle::AesGcm::new(&[b'A'; 32]).unwrap());
94+
95+
// Create a keyset
96+
let key_data = tink_tests::new_key_data("some type url", &[0], KeyMaterialType::Symmetric);
97+
let key = tink_tests::new_key(
98+
&key_data,
99+
tink_proto::KeyStatusType::Enabled,
100+
1,
101+
tink_proto::OutputPrefixType::Tink,
102+
);
103+
let ks = tink_tests::new_keyset(1, vec![key]);
104+
let h = insecure::new_handle(ks).unwrap();
105+
106+
let mem_keyset = &mut tink_core::keyset::MemReaderWriter::default();
107+
assert!(h
108+
.write_with_associated_data(mem_keyset, main_key.clone(), &[0x01, 0x02])
109+
.is_ok());
110+
let h2 = Handle::read_with_associated_data(mem_keyset, main_key, &[0x01, 0x02]).unwrap();
111+
assert_eq!(
112+
insecure::keyset_material(&h),
113+
insecure::keyset_material(&h2),
114+
"Decrypt failed: got {:?}, want {:?}",
115+
h2,
116+
h
117+
);
118+
}
119+
#[test]
120+
fn test_read_with_mismatched_associated_data() {
121+
let main_key = Box::new(tink_aead::subtle::AesGcm::new(&[b'A'; 32]).unwrap());
122+
123+
// Create a keyset
124+
let key_data = tink_tests::new_key_data("some type url", &[0], KeyMaterialType::Symmetric);
125+
let key = tink_tests::new_key(
126+
&key_data,
127+
tink_proto::KeyStatusType::Enabled,
128+
1,
129+
tink_proto::OutputPrefixType::Tink,
130+
);
131+
let ks = tink_tests::new_keyset(1, vec![key]);
132+
let h = insecure::new_handle(ks).unwrap();
133+
134+
let mem_keyset = &mut tink_core::keyset::MemReaderWriter::default();
135+
assert!(h
136+
.write_with_associated_data(mem_keyset, main_key.clone(), &[0x01, 0x02])
137+
.is_ok());
138+
let result = Handle::read_with_associated_data(mem_keyset, main_key, &[0x01, 0x03]);
139+
tink_tests::expect_err(result, "decryption failed");
140+
}
141+
91142
#[test]
92143
fn test_read_with_no_secrets() {
93144
// Create a keyset containing public key material

0 commit comments

Comments
 (0)