summaryrefslogtreecommitdiffstats
path: root/atuin-client/src/record/encryption.rs
diff options
context:
space:
mode:
Diffstat (limited to 'atuin-client/src/record/encryption.rs')
-rw-r--r--atuin-client/src/record/encryption.rs65
1 files changed, 31 insertions, 34 deletions
diff --git a/atuin-client/src/record/encryption.rs b/atuin-client/src/record/encryption.rs
index f14bf027..6760d97b 100644
--- a/atuin-client/src/record/encryption.rs
+++ b/atuin-client/src/record/encryption.rs
@@ -1,4 +1,6 @@
-use atuin_common::record::{AdditionalData, DecryptedData, EncryptedData, Encryption};
+use atuin_common::record::{
+ AdditionalData, DecryptedData, EncryptedData, Encryption, HostId, RecordId,
+};
use base64::{engine::general_purpose, Engine};
use eyre::{ensure, Context, Result};
use rusty_paserk::{Key, KeyId, Local, PieWrappedKey};
@@ -158,10 +160,11 @@ struct AtuinFooter {
// This cannot be changed, otherwise it breaks the authenticated encryption.
#[derive(Debug, Copy, Clone, Serialize)]
struct Assertions<'a> {
- id: &'a str,
+ id: &'a RecordId,
version: &'a str,
tag: &'a str,
- host: &'a str,
+ host: &'a HostId,
+ parent: Option<&'a RecordId>,
}
impl<'a> From<AdditionalData<'a>> for Assertions<'a> {
@@ -171,6 +174,7 @@ impl<'a> From<AdditionalData<'a>> for Assertions<'a> {
version: ad.version,
tag: ad.tag,
host: ad.host,
+ parent: ad.parent,
}
}
}
@@ -183,7 +187,7 @@ impl Assertions<'_> {
#[cfg(test)]
mod tests {
- use atuin_common::record::Record;
+ use atuin_common::{record::Record, utils::uuid_v7};
use super::*;
@@ -192,10 +196,11 @@ mod tests {
let key = Key::<V4, Local>::new_os_random();
let ad = AdditionalData {
- id: "foo",
+ id: &RecordId(uuid_v7()),
version: "v0",
tag: "kv",
- host: "1234",
+ host: &HostId(uuid_v7()),
+ parent: None,
};
let data = DecryptedData(vec![1, 2, 3, 4]);
@@ -210,10 +215,11 @@ mod tests {
let key = Key::<V4, Local>::new_os_random();
let ad = AdditionalData {
- id: "foo",
+ id: &RecordId(uuid_v7()),
version: "v0",
tag: "kv",
- host: "1234",
+ host: &HostId(uuid_v7()),
+ parent: None,
};
let data = DecryptedData(vec![1, 2, 3, 4]);
@@ -233,10 +239,11 @@ mod tests {
let fake_key = Key::<V4, Local>::new_os_random();
let ad = AdditionalData {
- id: "foo",
+ id: &RecordId(uuid_v7()),
version: "v0",
tag: "kv",
- host: "1234",
+ host: &HostId(uuid_v7()),
+ parent: None,
};
let data = DecryptedData(vec![1, 2, 3, 4]);
@@ -250,10 +257,11 @@ mod tests {
let key = Key::<V4, Local>::new_os_random();
let ad = AdditionalData {
- id: "foo",
+ id: &RecordId(uuid_v7()),
version: "v0",
tag: "kv",
- host: "1234",
+ host: &HostId(uuid_v7()),
+ parent: None,
};
let data = DecryptedData(vec![1, 2, 3, 4]);
@@ -261,10 +269,8 @@ mod tests {
let encrypted = PASETO_V4::encrypt(data, ad, &key.to_bytes());
let ad = AdditionalData {
- id: "foo1",
- version: "v0",
- tag: "kv",
- host: "1234",
+ id: &RecordId(uuid_v7()),
+ ..ad
};
let _ = PASETO_V4::decrypt(encrypted, ad, &key.to_bytes()).unwrap_err();
}
@@ -275,10 +281,11 @@ mod tests {
let key2 = Key::<V4, Local>::new_os_random();
let ad = AdditionalData {
- id: "foo",
+ id: &RecordId(uuid_v7()),
version: "v0",
tag: "kv",
- host: "1234",
+ host: &HostId(uuid_v7()),
+ parent: None,
};
let data = DecryptedData(vec![1, 2, 3, 4]);
@@ -304,10 +311,10 @@ mod tests {
fn full_record_round_trip() {
let key = [0x55; 32];
let record = Record::builder()
- .id("1".to_owned())
+ .id(RecordId(uuid_v7()))
.version("v0".to_owned())
.tag("kv".to_owned())
- .host("host1".to_owned())
+ .host(HostId(uuid_v7()))
.timestamp(1687244806000000)
.data(DecryptedData(vec![1, 2, 3, 4]))
.build();
@@ -316,30 +323,20 @@ mod tests {
assert!(!encrypted.data.data.is_empty());
assert!(!encrypted.data.content_encryption_key.is_empty());
- assert_eq!(encrypted.id, "1");
- assert_eq!(encrypted.host, "host1");
- assert_eq!(encrypted.version, "v0");
- assert_eq!(encrypted.tag, "kv");
- assert_eq!(encrypted.timestamp, 1687244806000000);
let decrypted = encrypted.decrypt::<PASETO_V4>(&key).unwrap();
assert_eq!(decrypted.data.0, [1, 2, 3, 4]);
- assert_eq!(decrypted.id, "1");
- assert_eq!(decrypted.host, "host1");
- assert_eq!(decrypted.version, "v0");
- assert_eq!(decrypted.tag, "kv");
- assert_eq!(decrypted.timestamp, 1687244806000000);
}
#[test]
fn full_record_round_trip_fail() {
let key = [0x55; 32];
let record = Record::builder()
- .id("1".to_owned())
+ .id(RecordId(uuid_v7()))
.version("v0".to_owned())
.tag("kv".to_owned())
- .host("host1".to_owned())
+ .host(HostId(uuid_v7()))
.timestamp(1687244806000000)
.data(DecryptedData(vec![1, 2, 3, 4]))
.build();
@@ -347,13 +344,13 @@ mod tests {
let encrypted = record.encrypt::<PASETO_V4>(&key);
let mut enc1 = encrypted.clone();
- enc1.host = "host2".to_owned();
+ enc1.host = HostId(uuid_v7());
let _ = enc1
.decrypt::<PASETO_V4>(&key)
.expect_err("tampering with the host should result in auth failure");
let mut enc2 = encrypted;
- enc2.id = "2".to_owned();
+ enc2.id = RecordId(uuid_v7());
let _ = enc2
.decrypt::<PASETO_V4>(&key)
.expect_err("tampering with the id should result in auth failure");