Skip to content

Commit 7808367

Browse files
authored
Merge pull request #52 from godaddy/bug-fix-3
fix: KMS envelope base64 serialization for Go interop
2 parents 6fbb21f + 1977e03 commit 7808367

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

asherah/src/kms_aws_envelope.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ pub struct AwsKmsEnvelope<A: AEAD + Send + Sync + 'static> {
2323

2424
#[derive(serde::Serialize, serde::Deserialize)]
2525
struct KekEnvelope {
26-
#[serde(rename = "encryptedKey")]
26+
#[serde(
27+
rename = "encryptedKey",
28+
serialize_with = "crate::types::serde_base64::serialize",
29+
deserialize_with = "crate::types::serde_base64::deserialize"
30+
)]
2731
encrypted_key: Vec<u8>,
2832
#[serde(rename = "kmsKeks")]
2933
keks: Vec<RegionalKek>,
@@ -35,7 +39,11 @@ struct RegionalKek {
3539
region: String,
3640
#[serde(rename = "arn")]
3741
arn: String,
38-
#[serde(rename = "encryptedKek")]
42+
#[serde(
43+
rename = "encryptedKek",
44+
serialize_with = "crate::types::serde_base64::serialize",
45+
deserialize_with = "crate::types::serde_base64::deserialize"
46+
)]
3947
encrypted_kek: Vec<u8>,
4048
}
4149

@@ -350,6 +358,15 @@ mod tests {
350358
assert!(j.contains("\"region\""));
351359
assert!(j.contains("\"arn\""));
352360
assert!(j.contains("\"encryptedKek\""));
361+
// Byte fields must be base64 strings, not JSON arrays
362+
assert!(
363+
j.contains("\"encryptedKey\":\""),
364+
"encryptedKey should be a base64 string, got: {j}"
365+
);
366+
assert!(
367+
j.contains("\"encryptedKek\":\""),
368+
"encryptedKek should be a base64 string, got: {j}"
369+
);
353370
// Roundtrip
354371
let back: KekEnvelope = serde_json::from_str(&j)?;
355372
assert_eq!(back.encrypted_key, vec![1, 2, 3]);
@@ -360,6 +377,30 @@ mod tests {
360377
Ok(())
361378
}
362379

380+
#[test]
381+
fn test_deserialize_go_produced_kms_envelope() {
382+
// Go asherah produces base64-encoded byte fields in KMS envelope JSON.
383+
// This test ensures Rust can deserialize that format.
384+
let go_json = r#"{
385+
"encryptedKey": "AQIDBAU=",
386+
"kmsKeks": [{
387+
"region": "us-west-2",
388+
"arn": "arn:aws:kms:us-west-2:111122223333:key/example",
389+
"encryptedKek": "CQgHBgU="
390+
}]
391+
}"#;
392+
let env: KekEnvelope =
393+
serde_json::from_str(go_json).expect("should deserialize Go-produced KMS envelope");
394+
assert_eq!(env.encrypted_key, vec![1, 2, 3, 4, 5]);
395+
assert_eq!(env.keks.len(), 1);
396+
assert_eq!(env.keks[0].region, "us-west-2");
397+
assert_eq!(
398+
env.keks[0].arn,
399+
"arn:aws:kms:us-west-2:111122223333:key/example"
400+
);
401+
assert_eq!(env.keks[0].encrypted_kek, vec![9, 8, 7, 6, 5]);
402+
}
403+
363404
#[test]
364405
fn new_multi_empty_entries_fails() {
365406
let aead = Arc::new(crate::aead::AES256GCM::new());

asherah/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub struct DataRowRecord {
5151
pub data: Vec<u8>,
5252
}
5353

54-
mod serde_base64 {
54+
pub(crate) mod serde_base64 {
5555
use base64::Engine;
5656
use serde::{de::Error, Deserialize, Deserializer, Serializer};
5757

0 commit comments

Comments
 (0)