Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions .github/workflows/tls_codec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,23 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
targets: ${{ matrix.target }}
targets: ${{ matrix.targets }}
- run: ${{ matrix.deps }}
- uses: RustCrypto/actions/cargo-hack-install@master
- run: cargo hack test --feature-powerset
- run: cargo hack test -p tls_codec_derive --feature-powerset --test encode\* --test decode\*
- run: cargo hack test -p tls_codec_derive --feature-powerset --doc
- run: cargo hack test --target ${{ matrix.targets }} --feature-powerset
- run: cargo hack test --target ${{ matrix.targets }} -p tls_codec_derive --feature-powerset --test encode\* --test decode\*
- run: cargo hack test --target ${{ matrix.targets }} -p tls_codec_derive --feature-powerset --doc
- run: cargo test --target ${{ matrix.targets }} --benches

fuzz:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@nightly
- uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- run: |
for fuzz_target in inverse string deserialize bytes_inverse; do
cargo fuzz run --target x86_64-unknown-linux-gnu "$fuzz_target" -- -max_total_time=5
done
41 changes: 38 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tls_codec/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## 0.4.3

- [#2351](https://github.com/RustCrypto/formats/pull/2351): Implement `Size`, `SerializeBytes`, and `DeserializeBytes` for `String` (and `Size`/`SerializeBytes` for `str` / `&str`), encoding the UTF-8 bytes as a `VLByteVec`. Also implement `SerializeBytes` for `ContentLength` and `VLByteSlice`.
- [#2322](https://github.com/RustCrypto/formats/pull/2322): Add `VLByteVec` and `SecretVLByteVec`, which are `#[serde(transparent)]` wrappers serializing via `serde_bytes`. They produce a much more compact representation in `serde` formats that distinguish byte arrays from sequences of `u8` (e.g. CBOR, MessagePack, bincode). Their `serde` output is not compatible with `VLBytes` / `SecretVLBytes`, but their `Deserialize` impls are backwards-compatible: in self-describing `serde` formats they also accept the legacy `VLBytes` / `SecretVLBytes` encoding (a struct with a `vec` field containing a sequence of `u8`). Deprecate `VLBytes` and `SecretVLBytes` in favour of `VLByteVec` and `SecretVLByteVec`.
- [#1656](https://github.com/RustCrypto/formats/pull/1656) Add `TlsVarInt` type for variable-length integers.

### Changed
- Bumped minimum dependency versions: `zeroize` 1.8 → 1.9, `serde` 1.0.184 → 1.0.228, `serde_bytes` 0.11.17 → 0.11.19.

### Fixed
- [#2348](https://github.com/RustCrypto/formats/pull/2348) Use `write_all` everywhere instead of write to prevent partial writes from going undetected. The `Error::InvalidWriteLength` variant is deprecated as it is no longer returned.
- [#2365](https://github.com/RustCrypto/formats/pull/2365) Element-vector deserialization (`Vec<T>`, `TlsVecU*<T>`, `SecretTlsVecU*<T>`), for both the `Deserialize` (`std::io::Read`) and `DeserializeBytes` implementations, now measures actual byte consumption instead of relying on `tls_serialized_len()` and enforces the declared length exactly. This makes the two implementations agree for non-canonical inner encodings (e.g. non-minimal varint lengths) and rejects input whose elements overshoot the declared vector boundary.
- Element vectors now reject zero-length elements that would otherwise never advance the read cursor, preventing an infinite loop and unbounded allocation on malicious input.
- `DeserializeBytes` for `TlsByteVecU*` now uses `checked_add` when computing the content range, returning `Error::InvalidVectorLength` instead of overflowing `usize` on targets where the length field is as wide as the pointer width. (The `VLBytes` / `VLByteVec` deserialization paths were unaffected: the byte-slice path slices via `get(..length)` and the `Read` path bounds allocation via `isize::MAX`, so neither computes an overflowing sum.)
- Read-based byte-vector deserialization (`TlsByteVecU*`, `VLBytes`, `VLByteVec`) no longer eagerly allocates a buffer sized by the untrusted length field, avoiding large allocations from bogus length prefixes. The `serde` `Deserialize` for `VLByteVec` / `SecretVLByteVec` likewise caps the initial allocation derived from an untrusted `size_hint`.
- Allocation sites now reject capacities exceeding `isize::MAX` (returning `Error::InvalidVectorLength`) instead of panicking in `Vec::with_capacity`; reachable on 32-bit targets.
- Fixed swapped doc comments on the `Deserializable*` / `Undeserializable*` type aliases generated by `#[conditionally_deserializable]`.
- Avoid potential overflows when summing serialized lengths. On 32-bit targets, serialization (including `tls_codec_derive`-generated `Size` impls) can now return `Error::InvalidVectorLength` where the length sum previously wrapped `usize` and produced a truncated, mismatched length prefix on the wire.

## 0.4.2

Expand Down
10 changes: 5 additions & 5 deletions tls_codec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tls_codec"
version = "0.4.2"
version = "0.4.3-pre.1"
authors = ["RustCrypto Developers"]
license = "Apache-2.0 OR MIT"
documentation = "https://docs.rs/tls_codec/"
Expand All @@ -12,13 +12,13 @@ edition = "2024"
rust-version = "1.85"

[dependencies]
zeroize = { version = "1.8", default-features = false, features = ["alloc"] }
zeroize = { version = "1.9", default-features = false, features = ["alloc"] }

# optional dependencies
arbitrary = { version = "1.4", features = ["derive"], optional = true }
tls_codec_derive = { version = "=0.4.2", path = "./derive", optional = true }
serde = { version = "1.0.184", features = ["derive"], optional = true }
serde_bytes = { version = "0.11.17", optional = true }
tls_codec_derive = { version = "=0.4.3-pre.1", path = "./derive", optional = true }
serde = { version = "1.0.228", features = ["derive"], optional = true }
serde_bytes = { version = "0.11.19", optional = true }

[dev-dependencies]
criterion = { version = "0.6", default-features = false }
Expand Down
37 changes: 36 additions & 1 deletion tls_codec/benches/tls_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,41 @@ fn byte_vector(c: &mut Criterion) {
TlsByteSliceU32(&long_vec).tls_serialize_detached().unwrap()
},
|serialized_long_vec| {
TlsVecU32::<u8>::tls_deserialize(&mut serialized_long_vec.as_slice()).unwrap()
// Decode into the byte-vector type so this exercises the
// bulk `read_bytes_bounded` path, not the generic per-element
// loop (`TlsVecU32`).
TlsByteVecU32::tls_deserialize(&mut serialized_long_vec.as_slice()).unwrap()
},
BatchSize::SmallInput,
)
});
}

/// Benchmarks the generic per-element deserialize loop with a multi-byte
/// element type, so the loop's per-element bookkeeping isn't hidden behind
/// trivial `u8` decoding.
fn typed_vector(c: &mut Criterion) {
use tls_codec::*;
c.bench_function("TLS Serialize Typed Vector", |b| {
b.iter_batched_ref(
|| {
(
TlsVecU32::from(vec![0x7777u16; N]),
Vec::with_capacity(8 + 2 * N),
)
},
|(long_vec, buf)| long_vec.tls_serialize(buf).unwrap(),
BatchSize::SmallInput,
)
});
c.bench_function("TLS Deserialize Typed Vector", |b| {
b.iter_batched_ref(
|| {
let long_vec = vec![0x7777u16; N];
TlsSliceU32(&long_vec).tls_serialize_detached().unwrap()
},
|serialized_long_vec| {
TlsVecU32::<u16>::tls_deserialize(&mut serialized_long_vec.as_slice()).unwrap()
},
BatchSize::SmallInput,
)
Expand Down Expand Up @@ -78,6 +112,7 @@ fn slice(c: &mut Criterion) {
}
fn benchmark(c: &mut Criterion) {
vector(c);
typed_vector(c);
slice(c);
byte_vector(c);
byte_slice(c);
Expand Down
2 changes: 1 addition & 1 deletion tls_codec/derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tls_codec_derive"
version = "0.4.2"
version = "0.4.3-pre.1"
authors = ["RustCrypto Developers"]
license = "Apache-2.0 OR MIT"
documentation = "https://docs.rs/tls_codec_derive/"
Expand Down
Loading
Loading