feat(native-rust): message body framing (framed and non-framed)#918
Conversation
There was a problem hiding this comment.
Pull request overview
Implements Rust-native message body framing per the spec, covering framed-body encryption/serialization, framed/non-framed deserialization, and a large set of format- and client-API-aligned tests.
Changes:
- Added message body module surface plus framed-body encrypt/serialize and decrypt/deserialize implementations.
- Implemented non-framed body deserialization path (write-path intentionally not implemented).
- Added extensive spec-citation tests covering field ordering, sizes, bounds, and tamper cases for body frames and header/body boundary expectations.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
esdk/src/message/body/mod.rs |
Introduces the message body module surface and re-exports body submodules. |
esdk/src/message/body/body_encrypt.rs |
Implements framed body encryption and on-wire frame serialization. |
esdk/src/message/body/body_decrypt.rs |
Implements framed body parsing/decryption and non-framed body parsing/decryption. |
esdk/tests/test_message_body_format.rs |
Adds spec-driven tests for framed and non-framed body format requirements and ordering. |
esdk/tests/test_construct_the_body.rs |
Adds tests for encrypt API “construct the body” behavior and plaintext length bound enforcement. |
esdk/tests/test_construct_a_frame.rs |
Adds tests for encrypt API “construct a frame” requirements (AAD/IV/seq/content length). |
esdk/tests/test_authentication_tag.rs |
Adds tests validating header authentication tag layout and tamper failures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ngth zeros Found by Copilot review on PR #918. In read_and_decrypt_framed_message_body, the final-frame branch's empty-content case (`enc_content.is_empty()`) was originally written for the exact-multiple case where an empty final frame follows one or more regular frames; the comment 'final frame is empty, so return last full frame' captures that intent. The preallocated `result` buffer (vec![0; frame_length_usize]) holds the last regular frame's plaintext at that point, so returning it unchanged is correct. But when the entire plaintext is empty (encrypt produces a single empty final frame, no prior regular frames), `result` is still the initial zero-filled buffer. Returning it leaks frame_length zero bytes to the caller — empty plaintext round-trips to (e.g.) 4096 zero bytes. Minimal fix: when the empty final frame is also the FIRST frame (expected_frame == START_SEQUENCE_NUMBER), call result.clear() so an empty Vec is returned. The exact-multiple case is unchanged. Tests: - test_empty_plaintext_round_trip_returns_empty: regression test for the fixed empty-plaintext path. - test_exact_multiple_round_trip_preserves_last_frame: confirms the original exact-multiple behavior (last regular frame returned for empty final) still round-trips correctly.
Re-do of the deletion in c823f44, which dropped 6 type=test annotations without preserving them. This pass keeps every spec quote alive: - 2 AAD-input quotes moved into the existing AEAD-inputs round-trip test. - 9 'MUST be interpreted as bytes' source-side annotations on body_decrypt.rs are upgraded from implementation+reason to type=implication. - 1 deletion (test_exact_multiple_round_trip_preserves_last_frame) was already redundant with a sibling test in the same file.
josecorella
left a comment
There was a problem hiding this comment.
have to still review source and test_message_body_format
but this is is a pattern I saw throughout the other test files, what do you think?
josecorella
left a comment
There was a problem hiding this comment.
just need to review decrypt but there's a potential error on 186, lmk
josecorella
left a comment
There was a problem hiding this comment.
decrypt looks good - only outstanding issue is the comment i left on encrypt
Implements message body framing — both framed and non-framed body serialization and deserialization — per message-body.md.
Scope:
esdk/src/message/body/mod.rs— body module surface and shared body types.esdk/src/message/body/body_encrypt.rs— body serialization (framed and non-framed).esdk/src/message/body/body_decrypt.rs— body deserialization (framed and non-framed).esdk/tests/test_message_body_format.rs,esdk/tests/test_construct_the_body.rs,esdk/tests/test_construct_a_frame.rs,esdk/tests/test_authentication_tag.rs.Body AAD construction is reviewed separately in #900 (
message-body-aad). Headers and footer that bracket the body are reviewed in #909 / #901 / #898 respectively.Note: CI does not run on this PR. This branch is scoped for focused review and intentionally omits test helpers, scaffolding, and other supporting code. Full code — including helpers, test infrastructure, and working tests — lives on the
aws-crypto-rust/unreviewedbranch.If you want more context or to actually run the tests, see
aws-crypto-rust/unreviewed.Related spec: data-format/message-body.md