Support spec_version 1.0.x for better interoperability with other TUF implementations#417
Conversation
d25074a to
95c431c
Compare
| // according to the SemVer spec, because it is already baked into some of the old roots. | ||
| fn valid_spec_version(other: &str) -> bool { | ||
| matches!(other, "1.0" | "1.0.0") | ||
| if other == SPEC_VERSION { |
There was a problem hiding this comment.
Thanks for this! Looking through your research, I think we should follow the spec and just parse the string as a semver string, preferably using the semver crate. With something like:
const SPEC_VERSION = semver::Version::new(1, 0, 0);
...
fn valid_spec_version(version_string: &str) -> bool {
/////////////////////////////////////////
// TUF-1.0.34 §4.3 (https://theupdateframework.github.io/specification/v1.0.34/#spec_version):
//
// A string that contains the version number of the TUF specification. Its format follows
// the [Semantic Versioning 2.0.0 (semver)](https://semver.org/spec/v2.0.0.html)
// specification. Metadata is written according to version "spec_version" of the
// specification, and clients MUST verify that "spec_version" matches the expected version
// number. Adopters are free to determine what is considered a match (e.g., the version
// number exactly, or perhaps only the major version number
// (major.minor.fix).https://theupdateframework.github.io/specification/v1.0.34/#file-formats-root
let version = semver::Version::parse(version_string) else {
// Support parsing `1.0` for legacy versions
return version_string == "1.0";
};
version.major == SPEC_VERSION.major
}
At this point I think we can switch our spec version to 1.0.0, and eventually update the metadata version to 1.0.x once I finish updating support for the latest spec.
There was a problem hiding this comment.
Thanks for the suggestion.
I updated the implementation to use the semver
crate and defined the supported spec version as Version::new(1, 0, 0).
As part of this change, metadata generated by the test helpers now uses
"1.0.0" instead of "1.0". I updated the affected test fixtures and
expected signatures accordingly. I also changed the spec version to "1.0.0"
in tests that are intended to fail for another validation reason, so that they
continue to exercise the intended failure path.
To preserve compatibility with legacy metadata, I added
deserialize_json_root_accepts_legacy_1_0_spec_version, which verifies that
we still accept "1.0".
The interop metadata fixtures also needed to be regenerated because the
updated spec_version changes the signed metadata. I regenerated them using
interop-tests/tests/metadata/regenerate-metadata.sh. The interop tests pass
for both consistent snapshot configurations.
Please let me know if you see any issues with these changes. I would be happy
to address them.
95c431c to
5f4d442
Compare
Update generated interop fixtures after the specification version changed from 1.0 to 1.0.0.
|
Could you do a |
Remove unnecessary whitespace
|
My apologies, I forgot to run |
description
I am evaluating
rust-tufas a client-side library for embedded Linux / CIP1 use cases.As part of that work, I tested a client based on
rust-tufwith other TUF repositories and server-side implementations.I found an interoperability issue. The
rust-tufclient currently acceptsspec_versionvalues such as1.0and1.0.0.But current TUF metadata in the ecosystem often uses
1.0.x.This PR keeps compatibility with the old
1.0value. It also accepts numeric1.0.xvalues such as1.0.31.I kept this change small.
1.0is still accepted for compatibility with existing metadata1.0.xis accepted1.1.0and2.0.0are still rejected1.x.yThe TUF specification leaves this point open. It says that
spec_versionuses SemVer, but adopters can decide what counts as a match 2.Because of that, I am proposing a small interoperability fix here, not a broader policy change.
I also checked a few other TUF projects.
tuf-conformanceincludes metadata withspec_version: "1.0.31"3python-tufaccepts numericX.Y/X.Y.Zand matches on major version 4tuf-jsseems to use almost the same policy 5go-tufwrites1.0.31, and from a quick look at the current source I could not find the same strictspec_versioncheck in the main parse path 6There is still a bigger design question: should
rust-tufaccept1.x.ymore generally, likepython-tufandtuf-js?I think that question should be decided separately.
For this PR, I wanted to focus on the immediate interoperability issue reported in #410.
If maintainers prefer a different direction, I am happy to adjust this PR or split follow-up interoperability changes into separate PRs.
verification
spec_versionvalidation testspec_version: "1.0.31"spec_versionClick to expand
cargo test -p tuf --lib pouf::pouf1::shims::test::spec_version_validation -- --exactcargo test -p tuf --lib metadata::test::deserialize_json_root_accepts_1_0_x_spec_version -- --exactcargo test -q-> all tests passed
REF
1.0.0as valid #386Footnotes
https://cip-project.org/ ↩
https://github.com/theupdateframework/specification/blob/v1.0.31/tuf-spec.md?plain=1#L690 ↩
https://github.com/theupdateframework/tuf-conformance/blob/eeb82bff9ce7e19133d24bc7bd44a7e8908546ed/tuf_conformance/static_data/tuf-on-ci-0.11/metadata/1.root.json#L60 ↩
https://github.com/theupdateframework/python-tuf/blob/9a3c3046d6ffdc9d90ec21ce5237721bcd985652/tuf/api/_payload.py#L137 ↩
https://github.com/theupdateframework/tuf-js/blob/a399ce87d8d908f64d53696a673420193424e0de/packages/models/src/base.ts#L41 ↩
metadata/types.go,metadata/metadata.go,metadata/marshal.go↩